From 5b406d00fc62383993f0020d3a919b2bb710a668 Mon Sep 17 00:00:00 2001 From: Dharmit Shah Date: Wed, 25 Sep 2024 11:03:54 +0530 Subject: [PATCH 1/6] VERSION=105.1.0-rc.1+up61.3.2 CHART=rancher-monitoring-crd make remove Signed-off-by: Dharmit Shah --- ...r-monitoring-crd-105.1.0-rc.1+up61.3.2.tgz | Bin 330167 -> 0 bytes .../105.1.0-rc.1+up61.3.2/Chart.yaml | 10 -- .../105.1.0-rc.1+up61.3.2/README.md | 24 ----- .../files/crd-manifest.tgz | Bin 331306 -> 0 bytes .../templates/_helpers.tpl | 30 ------ .../105.1.0-rc.1+up61.3.2/templates/jobs.yaml | 102 ------------------ .../templates/manifest.yaml | 8 -- .../105.1.0-rc.1+up61.3.2/templates/rbac.yaml | 76 ------------- .../templates/validate-psp-install.yaml | 7 -- .../105.1.0-rc.1+up61.3.2/values.yaml | 17 --- index.yaml | 14 --- 11 files changed, 288 deletions(-) delete mode 100644 assets/rancher-monitoring-crd/rancher-monitoring-crd-105.1.0-rc.1+up61.3.2.tgz delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/Chart.yaml delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/README.md delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/files/crd-manifest.tgz delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/jobs.yaml delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/manifest.yaml delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/rbac.yaml delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/values.yaml diff --git a/assets/rancher-monitoring-crd/rancher-monitoring-crd-105.1.0-rc.1+up61.3.2.tgz b/assets/rancher-monitoring-crd/rancher-monitoring-crd-105.1.0-rc.1+up61.3.2.tgz deleted file mode 100644 index 600326fecf8c5822a83ec1bba7c8e2af9d0fff65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 330167 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%0AYq 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 z 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�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

lgac9B)e~+9i)g{-GUvbc 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

BUnR{bH`mL0hr^mzvDNb&9ikTf! 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 rMBrh|~7mc8s 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ɲm`^cD>Ru&&RScC}4cXH}O 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 diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/_helpers.tpl b/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/_helpers.tpl deleted file mode 100644 index 146bc45a14..0000000000 --- a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/_helpers.tpl +++ /dev/null @@ -1,30 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/jobs.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/jobs.yaml deleted file mode 100644 index 6955e3b309..0000000000 --- a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/jobs.yaml +++ /dev/null @@ -1,102 +0,0 @@ -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ .Chart.Name }}-create - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Chart.Name }} - annotations: - "helm.sh/hook": post-install, post-upgrade, post-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed -spec: - template: - metadata: - name: {{ .Chart.Name }}-create - labels: - app: {{ .Chart.Name }} - spec: - serviceAccountName: {{ .Chart.Name }}-manager - securityContext: - runAsNonRoot: false - runAsUser: 0 - containers: - - name: create-crds - image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }} - imagePullPolicy: IfNotPresent - command: - - /bin/sh - - -c - - > - echo "Applying CRDs..."; - mkdir -p /etc/crd; - base64 -d /etc/config/crd-manifest.tgz.b64 | tar -xzv -C /etc/crd; - kubectl replace -Rf /etc/crd || kubectl create -Rf /etc/crd; - echo "Done!" - volumeMounts: - - name: crd-manifest - readOnly: true - mountPath: /etc/config - restartPolicy: OnFailure - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} - {{- if .Values.nodeSelector }} - {{- toYaml .Values.nodeSelector | nindent 8 }} - {{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} - {{- if .Values.tolerations }} - {{- toYaml .Values.tolerations | nindent 8 }} - {{- end }} - volumes: - - name: crd-manifest - configMap: - name: {{ .Chart.Name }}-manifest ---- -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ .Chart.Name }}-delete - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Chart.Name }} - annotations: - "helm.sh/hook": pre-delete - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed -spec: - template: - metadata: - name: {{ .Chart.Name }}-delete - labels: - app: {{ .Chart.Name }} - spec: - serviceAccountName: {{ .Chart.Name }}-manager - securityContext: - runAsNonRoot: false - runAsUser: 0 - containers: - - name: delete-crds - image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }} - imagePullPolicy: IfNotPresent - command: - - /bin/sh - - -c - - > - echo "Deleting CRDs..."; - mkdir -p /etc/crd; - base64 -d /etc/config/crd-manifest.tgz.b64 | tar -xzv -C /etc/crd; - kubectl delete --ignore-not-found=true -Rf /etc/crd; - volumeMounts: - - name: crd-manifest - readOnly: true - mountPath: /etc/config - restartPolicy: OnFailure - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} - {{- if .Values.nodeSelector }} - {{- toYaml .Values.nodeSelector | nindent 8 }} - {{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} - {{- if .Values.tolerations }} - {{- toYaml .Values.tolerations | nindent 8 }} - {{- end }} - volumes: - - name: crd-manifest - configMap: - name: {{ .Chart.Name }}-manifest diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/manifest.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/manifest.yaml deleted file mode 100644 index 8dc9dfb447..0000000000 --- a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/manifest.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Chart.Name }}-manifest - namespace: {{ .Release.Namespace }} -data: - crd-manifest.tgz.b64: - {{- .Files.Get "files/crd-manifest.tgz" | b64enc | indent 4 }} diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/rbac.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/rbac.yaml deleted file mode 100644 index a4d498b0fa..0000000000 --- a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/rbac.yaml +++ /dev/null @@ -1,76 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ .Chart.Name }}-manager - labels: - app: {{ .Chart.Name }}-manager -rules: -- apiGroups: - - apiextensions.k8s.io - resources: - - customresourcedefinitions - verbs: ['create', 'get', 'patch', 'delete', 'update', 'list'] -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ .Chart.Name }}-manager -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ .Chart.Name }}-manager - labels: - app: {{ .Chart.Name }}-manager -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ .Chart.Name }}-manager -subjects: -- kind: ServiceAccount - name: {{ .Chart.Name }}-manager - namespace: {{ .Release.Namespace }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Chart.Name }}-manager - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Chart.Name }}-manager ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ .Chart.Name }}-manager - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Chart.Name }}-manager -spec: - privileged: false - allowPrivilegeEscalation: false - hostNetwork: false - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 1 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 1 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'configMap' - - 'secret' -{{- end }} diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/validate-psp-install.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/values.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/values.yaml deleted file mode 100644 index 99e63600c4..0000000000 --- a/charts/rancher-monitoring-crd/105.1.0-rc.1+up61.3.2/values.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# Default values for rancher-monitoring-crd. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - -image: - repository: rancher/shell - tag: v0.2.1 - -nodeSelector: {} - -tolerations: [] diff --git a/index.yaml b/index.yaml index 070d878c42..89bbd07bd2 100755 --- a/index.yaml +++ b/index.yaml @@ -13222,20 +13222,6 @@ entries: - assets/rancher-monitoring/rancher-monitoring-101.0.0+up19.0.3.tgz version: 101.0.0+up19.0.3 rancher-monitoring-crd: - - annotations: - catalog.cattle.io/certified: rancher - catalog.cattle.io/hidden: "true" - catalog.cattle.io/namespace: cattle-monitoring-system - catalog.cattle.io/release-name: rancher-monitoring-crd - apiVersion: v2 - created: "2024-09-20T12:25:25.865438137-04:00" - description: Installs the CRDs for rancher-monitoring. - digest: cc4642513a31477671e30596f82d032bbc3e549bb9e469303931e25918805e77 - name: rancher-monitoring-crd - type: application - urls: - - assets/rancher-monitoring-crd/rancher-monitoring-crd-105.1.0-rc.1+up61.3.2.tgz - version: 105.1.0-rc.1+up61.3.2 - annotations: catalog.cattle.io/certified: rancher catalog.cattle.io/hidden: "true" From d5b46f647b1d14cb1d239c6ba80c91e08e27b3e1 Mon Sep 17 00:00:00 2001 From: Dharmit Shah Date: Wed, 25 Sep 2024 11:04:15 +0530 Subject: [PATCH 2/6] VERSION=105.1.0-rc.1+up61.3.2 CHART=rancher-monitoring make remove Signed-off-by: Dharmit Shah --- ...ncher-monitoring-105.1.0-rc.1+up61.3.2.tgz | Bin 488466 -> 0 bytes .../105.1.0-rc.1+up61.3.2/.editorconfig | 5 - .../105.1.0-rc.1+up61.3.2/.helmignore | 29 - .../105.1.0-rc.1+up61.3.2/CHANGELOG.md | 47 - .../105.1.0-rc.1+up61.3.2/CONTRIBUTING.md | 12 - .../105.1.0-rc.1+up61.3.2/Chart.yaml | 126 - .../105.1.0-rc.1+up61.3.2/README.md | 1140 ---- .../105.1.0-rc.1+up61.3.2/app-README.md | 46 - .../charts/grafana/.helmignore | 23 - .../charts/grafana/Chart.yaml | 41 - .../charts/grafana/README.md | 778 --- .../grafana/dashboards/custom-dashboard.json | 1 - .../charts/grafana/templates/NOTES.txt | 55 - .../charts/grafana/templates/_config.tpl | 172 - .../charts/grafana/templates/_helpers.tpl | 305 - .../charts/grafana/templates/_pod.tpl | 1306 ---- .../charts/grafana/templates/clusterrole.yaml | 25 - .../grafana/templates/clusterrolebinding.yaml | 24 - .../grafana/templates/configSecret.yaml | 43 - .../configmap-dashboard-provider.yaml | 15 - .../charts/grafana/templates/configmap.yaml | 20 - .../templates/dashboards-json-configmap.yaml | 38 - .../charts/grafana/templates/deployment.yaml | 53 - .../grafana/templates/extra-manifests.yaml | 4 - .../grafana/templates/headless-service.yaml | 22 - .../charts/grafana/templates/hpa.yaml | 52 - .../templates/image-renderer-deployment.yaml | 199 - .../grafana/templates/image-renderer-hpa.yaml | 47 - .../image-renderer-network-policy.yaml | 79 - .../templates/image-renderer-service.yaml | 31 - .../image-renderer-servicemonitor.yaml | 48 - .../charts/grafana/templates/ingress.yaml | 78 - .../grafana/templates/networkpolicy.yaml | 61 - .../grafana/templates/nginx-config.yaml | 94 - .../templates/poddisruptionbudget.yaml | 22 - .../grafana/templates/podsecuritypolicy.yaml | 45 - .../charts/grafana/templates/pvc.yaml | 41 - .../charts/grafana/templates/role.yaml | 32 - .../charts/grafana/templates/rolebinding.yaml | 25 - .../charts/grafana/templates/secret-env.yaml | 14 - .../charts/grafana/templates/secret.yaml | 16 - .../charts/grafana/templates/service.yaml | 67 - .../grafana/templates/serviceaccount.yaml | 17 - .../grafana/templates/servicemonitor.yaml | 66 - .../charts/grafana/templates/statefulset.yaml | 58 - .../templates/tests/test-configmap.yaml | 20 - .../tests/test-podsecuritypolicy.yaml | 32 - .../grafana/templates/tests/test-role.yaml | 17 - .../templates/tests/test-rolebinding.yaml | 20 - .../templates/tests/test-serviceaccount.yaml | 12 - .../charts/grafana/templates/tests/test.yaml | 53 - .../charts/grafana/values.yaml | 1365 ---- .../charts/hardenedKubelet/.helmignore | 23 - .../charts/hardenedKubelet/Chart.yaml | 15 - .../charts/hardenedKubelet/README.md | 90 - .../hardenedKubelet/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/hardenedKubelet/values.yaml | 166 - .../charts/hardenedNodeExporter/.helmignore | 23 - .../charts/hardenedNodeExporter/Chart.yaml | 15 - .../charts/hardenedNodeExporter/README.md | 90 - .../templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/hardenedNodeExporter/values.yaml | 166 - .../charts/k3sServer/.helmignore | 23 - .../charts/k3sServer/Chart.yaml | 15 - .../charts/k3sServer/README.md | 90 - .../charts/k3sServer/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../k3sServer/templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../k3sServer/templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/k3sServer/values.yaml | 166 - .../charts/kube-state-metrics/.helmignore | 21 - .../charts/kube-state-metrics/Chart.yaml | 32 - .../charts/kube-state-metrics/README.md | 85 - .../kube-state-metrics/templates/NOTES.txt | 23 - .../kube-state-metrics/templates/_helpers.tpl | 196 - .../templates/ciliumnetworkpolicy.yaml | 33 - .../templates/clusterrolebinding.yaml | 20 - .../templates/crs-configmap.yaml | 16 - .../templates/deployment.yaml | 313 - .../templates/extra-manifests.yaml | 4 - .../templates/kubeconfig-secret.yaml | 12 - .../templates/networkpolicy.yaml | 43 - .../kube-state-metrics/templates/pdb.yaml | 18 - .../templates/podsecuritypolicy.yaml | 39 - .../templates/psp-clusterrole.yaml | 19 - .../templates/psp-clusterrolebinding.yaml | 16 - .../templates/rbac-configmap.yaml | 22 - .../kube-state-metrics/templates/role.yaml | 215 - .../templates/rolebinding.yaml | 24 - .../kube-state-metrics/templates/service.yaml | 53 - .../templates/serviceaccount.yaml | 18 - .../templates/servicemonitor.yaml | 126 - .../templates/stsdiscovery-role.yaml | 26 - .../templates/stsdiscovery-rolebinding.yaml | 17 - .../templates/verticalpodautoscaler.yaml | 44 - .../charts/kube-state-metrics/values.yaml | 523 -- .../kubeAdmControllerManager/.helmignore | 23 - .../kubeAdmControllerManager/Chart.yaml | 15 - .../charts/kubeAdmControllerManager/README.md | 90 - .../templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../kubeAdmControllerManager/values.yaml | 166 - .../charts/kubeAdmEtcd/.helmignore | 23 - .../charts/kubeAdmEtcd/Chart.yaml | 15 - .../charts/kubeAdmEtcd/README.md | 90 - .../charts/kubeAdmEtcd/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../kubeAdmEtcd/templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/kubeAdmEtcd/values.yaml | 166 - .../charts/kubeAdmProxy/.helmignore | 23 - .../charts/kubeAdmProxy/Chart.yaml | 15 - .../charts/kubeAdmProxy/README.md | 90 - .../kubeAdmProxy/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/kubeAdmProxy/values.yaml | 166 - .../charts/kubeAdmScheduler/.helmignore | 23 - .../charts/kubeAdmScheduler/Chart.yaml | 15 - .../charts/kubeAdmScheduler/README.md | 90 - .../kubeAdmScheduler/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/kubeAdmScheduler/values.yaml | 166 - .../charts/prometheus-adapter/.helmignore | 21 - .../charts/prometheus-adapter/Chart.yaml | 27 - .../charts/prometheus-adapter/README.md | 160 - .../prometheus-adapter/templates/NOTES.txt | 9 - .../prometheus-adapter/templates/_helpers.tpl | 113 - .../templates/certmanager.yaml | 76 - .../cluster-role-binding-auth-delegator.yaml | 20 - .../cluster-role-binding-auth-reader.yaml | 20 - .../cluster-role-binding-resource-reader.yaml | 20 - .../cluster-role-resource-reader.yaml | 24 - .../templates/configmap.yaml | 97 - .../templates/custom-metrics-apiservice.yaml | 34 - ...stom-metrics-cluster-role-binding-hpa.yaml | 24 - .../custom-metrics-cluster-role.yaml | 17 - .../templates/deployment.yaml | 151 - .../external-metrics-apiservice.yaml | 34 - ...rnal-metrics-cluster-role-binding-hpa.yaml | 20 - .../external-metrics-cluster-role.yaml | 20 - .../prometheus-adapter/templates/pdb.yaml | 23 - .../prometheus-adapter/templates/psp.yaml | 66 - .../resource-metrics-apiservice.yaml | 34 - ...resource-metrics-cluster-role-binding.yaml | 20 - .../resource-metrics-cluster-role.yaml | 23 - .../templates/role-binding-auth-reader.yaml | 21 - .../prometheus-adapter/templates/secret.yaml | 17 - .../prometheus-adapter/templates/service.yaml | 32 - .../templates/serviceaccount.yaml | 18 - .../charts/prometheus-adapter/values.yaml | 292 - .../prometheus-node-exporter/.helmignore | 21 - .../prometheus-node-exporter/Chart.yaml | 25 - .../charts/prometheus-node-exporter/README.md | 96 - .../templates/NOTES.txt | 29 - .../templates/_helpers.tpl | 236 - .../templates/clusterrole.yaml | 19 - .../templates/clusterrolebinding.yaml | 20 - .../templates/daemonset.yaml | 312 - .../templates/endpoints.yaml | 18 - .../templates/extra-manifests.yaml | 4 - .../templates/networkpolicy.yaml | 23 - .../templates/podmonitor.yaml | 91 - .../templates/psp-clusterrole.yaml | 14 - .../templates/psp-clusterrolebinding.yaml | 16 - .../templates/psp.yaml | 49 - .../templates/rbac-configmap.yaml | 16 - .../templates/service.yaml | 35 - .../templates/serviceaccount.yaml | 18 - .../templates/servicemonitor.yaml | 71 - .../templates/verticalpodautoscaler.yaml | 40 - .../prometheus-node-exporter/values.yaml | 539 -- .../charts/rke2ControllerManager/.helmignore | 23 - .../charts/rke2ControllerManager/Chart.yaml | 15 - .../charts/rke2ControllerManager/README.md | 90 - .../templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rke2ControllerManager/values.yaml | 166 - .../charts/rke2Etcd/.helmignore | 23 - .../charts/rke2Etcd/Chart.yaml | 15 - .../charts/rke2Etcd/README.md | 90 - .../charts/rke2Etcd/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../rke2Etcd/templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../rke2Etcd/templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rke2Etcd/values.yaml | 166 - .../charts/rke2IngressNginx/.helmignore | 23 - .../charts/rke2IngressNginx/Chart.yaml | 15 - .../charts/rke2IngressNginx/README.md | 90 - .../rke2IngressNginx/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rke2IngressNginx/values.yaml | 166 - .../charts/rke2Proxy/.helmignore | 23 - .../charts/rke2Proxy/Chart.yaml | 15 - .../charts/rke2Proxy/README.md | 90 - .../charts/rke2Proxy/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../rke2Proxy/templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../rke2Proxy/templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rke2Proxy/values.yaml | 166 - .../charts/rke2Scheduler/.helmignore | 23 - .../charts/rke2Scheduler/Chart.yaml | 15 - .../charts/rke2Scheduler/README.md | 90 - .../rke2Scheduler/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rke2Scheduler/values.yaml | 166 - .../charts/rkeControllerManager/.helmignore | 23 - .../charts/rkeControllerManager/Chart.yaml | 15 - .../charts/rkeControllerManager/README.md | 90 - .../templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rkeControllerManager/values.yaml | 166 - .../charts/rkeEtcd/.helmignore | 23 - .../charts/rkeEtcd/Chart.yaml | 15 - .../charts/rkeEtcd/README.md | 90 - .../charts/rkeEtcd/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../rkeEtcd/templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../rkeEtcd/templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rkeEtcd/values.yaml | 166 - .../charts/rkeIngressNginx/.helmignore | 23 - .../charts/rkeIngressNginx/Chart.yaml | 15 - .../charts/rkeIngressNginx/README.md | 90 - .../rkeIngressNginx/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rkeIngressNginx/values.yaml | 166 - .../charts/rkeProxy/.helmignore | 23 - .../charts/rkeProxy/Chart.yaml | 15 - .../charts/rkeProxy/README.md | 90 - .../charts/rkeProxy/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../rkeProxy/templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../rkeProxy/templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rkeProxy/values.yaml | 166 - .../charts/rkeScheduler/.helmignore | 23 - .../charts/rkeScheduler/Chart.yaml | 15 - .../charts/rkeScheduler/README.md | 90 - .../rkeScheduler/templates/_helpers.tpl | 170 - .../templates/pushprox-clients-rbac.yaml | 97 - .../templates/pushprox-clients.yaml | 157 - .../templates/pushprox-proxy-rbac.yaml | 68 - .../templates/pushprox-proxy.yaml | 57 - .../templates/pushprox-servicemonitor.yaml | 45 - .../templates/validate-install-crd.yaml | 14 - .../templates/validate-psp-install.yaml | 7 - .../charts/rkeScheduler/values.yaml | 166 - .../charts/windowsExporter/.helmignore | 21 - .../charts/windowsExporter/Chart.yaml | 17 - .../charts/windowsExporter/README.md | 42 - .../scripts/configure-firewall.ps1 | 31 - .../windowsExporter/templates/_helpers.tpl | 216 - .../windowsExporter/templates/config.yaml | 14 - .../windowsExporter/templates/daemonset.yaml | 200 - .../windowsExporter/templates/podmonitor.yaml | 91 - .../templates/scriptConfig.yaml | 14 - .../windowsExporter/templates/service.yaml | 32 - .../templates/serviceaccount.yaml | 17 - .../templates/servicemonitor.yaml | 75 - .../charts/windowsExporter/values.yaml | 366 -- .../files/ingress-nginx/nginx.json | 1445 ----- .../request-handling-performance.json | 963 --- .../cluster/rancher-cluster-nodes.json | 793 --- .../rancher/cluster/rancher-cluster.json | 776 --- .../files/rancher/fleet/bundle.json | 246 - .../files/rancher/fleet/bundledeployment.json | 219 - .../files/rancher/fleet/cluster.json | 484 -- .../files/rancher/fleet/clustergroup.json | 468 -- .../rancher/fleet/controller-runtime.json | 454 -- .../files/rancher/fleet/gitrepo.json | 325 - .../rancher/home/rancher-default-home.json | 1290 ---- .../files/rancher/k8s/rancher-etcd-nodes.json | 687 -- .../files/rancher/k8s/rancher-etcd.json | 669 -- .../k8s/rancher-k8s-components-nodes.json | 527 -- .../rancher/k8s/rancher-k8s-components.json | 519 -- .../files/rancher/logging/fluentbit.json | 760 --- .../files/rancher/logging/fluentd.json | 3221 ---------- .../rancher/nodes/rancher-node-detail.json | 805 --- .../files/rancher/nodes/rancher-node.json | 792 --- .../performance/performance-debugging.json | 1652 ----- .../rancher/pods/rancher-pod-containers.json | 636 -- .../files/rancher/pods/rancher-pod.json | 636 -- .../workloads/rancher-workload-pods.json | 652 -- .../rancher/workloads/rancher-workload.json | 652 -- .../delete-workloads-with-old-labels.sh | 14 - .../105.1.0-rc.1+up61.3.2/templates/NOTES.txt | 4 - .../templates/_helpers.tpl | 464 -- .../templates/alertmanager/alertmanager.yaml | 195 - .../templates/alertmanager/extrasecret.yaml | 20 - .../templates/alertmanager/ingress.yaml | 78 - .../alertmanager/ingressperreplica.yaml | 67 - .../alertmanager/podDisruptionBudget.yaml | 21 - .../templates/alertmanager/psp-role.yaml | 23 - .../alertmanager/psp-rolebinding.yaml | 20 - .../templates/alertmanager/psp.yaml | 47 - .../templates/alertmanager/secret.yaml | 37 - .../templates/alertmanager/service.yaml | 72 - .../alertmanager/serviceaccount.yaml | 21 - .../alertmanager/servicemonitor.yaml | 84 - .../alertmanager/serviceperreplica.yaml | 49 - .../templates/exporters/core-dns/service.yaml | 28 - .../exporters/core-dns/servicemonitor.yaml | 58 - .../kube-api-server/servicemonitor.yaml | 57 - .../kube-controller-manager/endpoints.yaml | 22 - .../kube-controller-manager/service.yaml | 33 - .../servicemonitor.yaml | 69 - .../templates/exporters/kube-dns/service.yaml | 32 - .../exporters/kube-dns/servicemonitor.yaml | 71 - .../exporters/kube-etcd/endpoints.yaml | 20 - .../exporters/kube-etcd/service.yaml | 31 - .../exporters/kube-etcd/servicemonitor.yaml | 75 - .../exporters/kube-proxy/endpoints.yaml | 20 - .../exporters/kube-proxy/service.yaml | 31 - .../exporters/kube-proxy/servicemonitor.yaml | 63 - .../exporters/kube-scheduler/endpoints.yaml | 22 - .../exporters/kube-scheduler/service.yaml | 33 - .../kube-scheduler/servicemonitor.yaml | 69 - .../kube-state-metrics/validate.yaml | 7 - .../exporters/kubelet/servicemonitor.yaml | 246 - .../exporters/node-exporter/validate.yaml | 3 - .../templates/extra-objects.yaml | 4 - .../grafana/configmap-dashboards.yaml | 24 - .../grafana/configmaps-datasources.yaml | 81 - .../alertmanager-overview.yaml | 616 -- .../grafana/dashboards-1.14/apiserver.yaml | 1772 ------ .../dashboards-1.14/cluster-total.yaml | 1882 ------ .../dashboards-1.14/controller-manager.yaml | 1196 ---- .../grafana/dashboards-1.14/etcd.yaml | 1229 ---- .../dashboards-1.14/grafana-overview.yaml | 635 -- .../grafana/dashboards-1.14/k8s-coredns.yaml | 1534 ----- .../k8s-resources-cluster.yaml | 3088 --------- .../k8s-resources-multicluster.yaml | 24 - .../k8s-resources-namespace.yaml | 2797 --------- .../dashboards-1.14/k8s-resources-node.yaml | 1026 --- .../dashboards-1.14/k8s-resources-pod.yaml | 2469 -------- .../k8s-resources-windows-cluster.yaml | 24 - .../k8s-resources-windows-namespace.yaml | 24 - .../k8s-resources-windows-pod.yaml | 24 - .../k8s-resources-workload.yaml | 2024 ------ .../k8s-resources-workloads-namespace.yaml | 2189 ------- .../k8s-windows-cluster-rsrc-use.yaml | 24 - .../k8s-windows-node-rsrc-use.yaml | 24 - .../grafana/dashboards-1.14/kubelet.yaml | 2256 ------- .../dashboards-1.14/namespace-by-pod.yaml | 1464 ----- .../namespace-by-workload.yaml | 1736 ----- .../node-cluster-rsrc-use.yaml | 1063 ---- .../dashboards-1.14/node-rsrc-use.yaml | 1089 ---- .../grafana/dashboards-1.14/nodes-darwin.yaml | 1073 ---- .../grafana/dashboards-1.14/nodes.yaml | 1066 ---- .../persistentvolumesusage.yaml | 587 -- .../grafana/dashboards-1.14/pod-total.yaml | 1228 ---- .../prometheus-remote-write.yaml | 1674 ----- .../grafana/dashboards-1.14/prometheus.yaml | 1235 ---- .../grafana/dashboards-1.14/proxy.yaml | 1276 ---- .../grafana/dashboards-1.14/scheduler.yaml | 1118 ---- .../dashboards-1.14/workload-total.yaml | 1438 ----- .../templates/grafana/namespaces.yaml | 13 - .../_prometheus-operator.tpl | 7 - .../_prometheus-operator-webhook.tpl | 6 - .../deployment/deployment.yaml | 143 - .../admission-webhooks/deployment/pdb.yaml | 15 - .../deployment/service.yaml | 62 - .../deployment/serviceaccount.yaml | 15 - .../ciliumnetworkpolicy-createSecret.yaml | 36 - .../ciliumnetworkpolicy-patchWebhook.yaml | 36 - .../job-patch/clusterrole.yaml | 33 - .../job-patch/clusterrolebinding.yaml | 20 - .../job-patch/job-createSecret.yaml | 73 - .../job-patch/job-patchWebhook.yaml | 74 - .../job-patch/networkpolicy-createSecret.yaml | 33 - .../job-patch/networkpolicy-patchWebhook.yaml | 33 - .../admission-webhooks/job-patch/psp.yaml | 47 - .../admission-webhooks/job-patch/role.yaml | 21 - .../job-patch/rolebinding.yaml | 21 - .../job-patch/serviceaccount.yaml | 18 - .../mutatingWebhookConfiguration.yaml | 81 - .../validatingWebhookConfiguration.yaml | 81 - .../aggregate-clusterroles.yaml | 29 - .../prometheus-operator/certmanager.yaml | 55 - .../ciliumnetworkpolicy.yaml | 40 - .../prometheus-operator/clusterrole.yaml | 109 - .../clusterrolebinding.yaml | 16 - .../prometheus-operator/deployment.yaml | 207 - .../prometheus-operator/networkpolicy.yaml | 29 - .../prometheus-operator/psp-clusterrole.yaml | 21 - .../psp-clusterrolebinding.yaml | 18 - .../templates/prometheus-operator/psp.yaml | 46 - .../prometheus-operator/service.yaml | 61 - .../prometheus-operator/serviceaccount.yaml | 14 - .../prometheus-operator/servicemonitor.yaml | 57 - .../verticalpodautoscaler.yaml | 40 - .../templates/prometheus/_rules.tpl | 44 - .../additionalAlertRelabelConfigs.yaml | 16 - .../additionalAlertmanagerConfigs.yaml | 16 - .../prometheus/additionalPrometheusRules.yaml | 43 - .../prometheus/additionalScrapeConfigs.yaml | 20 - .../prometheus/ciliumnetworkpolicy.yaml | 27 - .../templates/prometheus/clusterrole.yaml | 43 - .../prometheus/clusterrolebinding.yaml | 18 - .../templates/prometheus/csi-secret.yaml | 12 - .../templates/prometheus/extrasecret.yaml | 20 - .../templates/prometheus/ingress.yaml | 77 - .../prometheus/ingressThanosSidecar.yaml | 77 - .../prometheus/ingressperreplica.yaml | 67 - .../templates/prometheus/networkpolicy.yaml | 34 - .../templates/prometheus/nginx-config.yaml | 68 - .../prometheus/podDisruptionBudget.yaml | 25 - .../templates/prometheus/podmonitors.yaml | 38 - .../templates/prometheus/prometheus.yaml | 481 -- .../templates/prometheus/psp-clusterrole.yaml | 22 - .../prometheus/psp-clusterrolebinding.yaml | 19 - .../templates/prometheus/psp.yaml | 58 - .../rules-1.14/alertmanager.rules.yaml | 305 - .../rules-1.14/config-reloaders.yaml | 57 - .../templates/prometheus/rules-1.14/etcd.yaml | 461 -- .../prometheus/rules-1.14/general.rules.yaml | 125 - ...les.container_cpu_usage_seconds_total.yaml | 43 - .../k8s.rules.container_memory_cache.yaml | 42 - .../k8s.rules.container_memory_rss.yaml | 42 - .../k8s.rules.container_memory_swap.yaml | 42 - ...es.container_memory_working_set_bytes.yaml | 42 - .../k8s.rules.container_resource.yaml | 168 - .../rules-1.14/k8s.rules.pod_owner.yaml | 107 - .../prometheus/rules-1.14/k8s.rules.yaml | 237 - .../kube-apiserver-availability.rules.yaml | 273 - .../kube-apiserver-burnrate.rules.yaml | 440 -- .../kube-apiserver-histogram.rules.yaml | 53 - .../rules-1.14/kube-apiserver-slos.yaml | 159 - .../kube-prometheus-general.rules.yaml | 49 - .../kube-prometheus-node-recording.rules.yaml | 93 - .../rules-1.14/kube-scheduler.rules.yaml | 135 - .../rules-1.14/kube-state-metrics.yaml | 152 - .../prometheus/rules-1.14/kubelet.rules.yaml | 65 - .../rules-1.14/kubernetes-apps.yaml | 568 -- .../rules-1.14/kubernetes-resources.yaml | 282 - .../rules-1.14/kubernetes-storage.yaml | 216 - .../kubernetes-system-apiserver.yaml | 193 - .../kubernetes-system-controller-manager.yaml | 57 - .../kubernetes-system-kube-proxy.yaml | 52 - .../rules-1.14/kubernetes-system-kubelet.yaml | 379 -- .../kubernetes-system-scheduler.yaml | 54 - .../rules-1.14/kubernetes-system.yaml | 87 - .../rules-1.14/node-exporter.rules.yaml | 188 - .../prometheus/rules-1.14/node-exporter.yaml | 801 --- .../prometheus/rules-1.14/node-network.yaml | 55 - .../prometheus/rules-1.14/node.rules.yaml | 109 - .../rules-1.14/prometheus-operator.yaml | 253 - .../prometheus/rules-1.14/prometheus.yaml | 735 --- .../rules-1.14/windows.node.rules.yaml | 301 - .../rules-1.14/windows.pod.rules.yaml | 158 - .../templates/prometheus/secret.yaml | 15 - .../templates/prometheus/service.yaml | 84 - .../prometheus/serviceThanosSidecar.yaml | 43 - .../serviceThanosSidecarExternal.yaml | 46 - .../templates/prometheus/serviceaccount.yaml | 21 - .../templates/prometheus/servicemonitor.yaml | 97 - .../servicemonitorThanosSidecar.yaml | 55 - .../templates/prometheus/servicemonitors.yaml | 47 - .../prometheus/serviceperreplica.yaml | 58 - .../rancher-monitoring/clusterrole.yaml | 135 - .../rancher-monitoring/config-role.yaml | 48 - .../rancher-monitoring/dashboard-role.yaml | 47 - .../addons/ingress-nginx-dashboard.yaml | 18 - .../rancher/cluster-dashboards.yaml | 17 - .../dashboards/rancher/default-dashboard.yaml | 17 - .../dashboards/rancher/fleet-dashboards.yaml | 17 - .../rancher/fluentbit-dashboard.yaml | 17 - .../dashboards/rancher/fluentd-dashboard.yaml | 17 - .../dashboards/rancher/k8s-dashboards.yaml | 31 - .../dashboards/rancher/nodes-dashboards.yaml | 17 - .../rancher/performance-dashboards.yaml | 18 - .../dashboards/rancher/pods-dashboards.yaml | 17 - .../rancher/workload-dashboards.yaml | 17 - .../exporters/fleet/servicemonitor.yaml | 53 - .../exporters/ingress-nginx/service.yaml | 27 - .../ingress-nginx/servicemonitor.yaml | 49 - .../exporters/rancher/servicemonitor.yaml | 58 - .../rancher-monitoring/hardened.yaml | 91 - .../rancher-monitoring/upgrade/configmap.yaml | 13 - .../rancher-monitoring/upgrade/job.yaml | 46 - .../rancher-monitoring/upgrade/rbac.yaml | 86 - .../templates/thanos-ruler/extrasecret.yaml | 20 - .../templates/thanos-ruler/ingress.yaml | 77 - .../thanos-ruler/podDisruptionBudget.yaml | 21 - .../templates/thanos-ruler/ruler.yaml | 200 - .../templates/thanos-ruler/secret.yaml | 26 - .../templates/thanos-ruler/service.yaml | 57 - .../thanos-ruler/serviceaccount.yaml | 20 - .../thanos-ruler/servicemonitor.yaml | 82 - .../templates/validate-install-crd.yaml | 23 - .../templates/validate-psp-install.yaml | 2 - .../105.1.0-rc.1+up61.3.2/values.yaml | 5565 ----------------- index.yaml | 130 - 577 files changed, 109461 deletions(-) delete mode 100644 assets/rancher-monitoring/rancher-monitoring-105.1.0-rc.1+up61.3.2.tgz delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/.editorconfig delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/CHANGELOG.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/CONTRIBUTING.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/app-README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/dashboards/custom-dashboard.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/NOTES.txt delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_config.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_pod.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configSecret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configmap-dashboard-provider.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configmap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/dashboards-json-configmap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/deployment.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/extra-manifests.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/headless-service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/hpa.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-deployment.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-hpa.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-network-policy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/ingress.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/networkpolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/nginx-config.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/poddisruptionbudget.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/podsecuritypolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/pvc.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/rolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/secret-env.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/secret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/statefulset.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-configmap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-podsecuritypolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-rolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/NOTES.txt delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/crs-configmap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/deployment.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/extra-manifests.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/kubeconfig-secret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/networkpolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/pdb.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/podsecuritypolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/rbac-configmap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/rolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/NOTES.txt delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/certmanager.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-reader.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/configmap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/deployment.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/pdb.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/psp.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/secret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/NOTES.txt delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/daemonset.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/endpoints.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/extra-manifests.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/networkpolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/podmonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/rbac-configmap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-clients.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/.helmignore delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/Chart.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/README.md delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/scripts/configure-firewall.ps1 delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/config.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/daemonset.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/podmonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/scriptConfig.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/values.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/ingress-nginx/nginx.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/ingress-nginx/request-handling-performance.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/cluster/rancher-cluster-nodes.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/cluster/rancher-cluster.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/bundle.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/bundledeployment.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/cluster.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/clustergroup.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/controller-runtime.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/gitrepo.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/home/rancher-default-home.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-etcd-nodes.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-etcd.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-k8s-components-nodes.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-k8s-components.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/logging/fluentbit.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/logging/fluentd.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/nodes/rancher-node-detail.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/nodes/rancher-node.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/performance/performance-debugging.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/pods/rancher-pod-containers.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/pods/rancher-pod.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/workloads/rancher-workload-pods.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/workloads/rancher-workload.json delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/upgrade/scripts/delete-workloads-with-old-labels.sh delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/NOTES.txt delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/_helpers.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/alertmanager.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/extrasecret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/ingress.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/ingressperreplica.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/podDisruptionBudget.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp-role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp-rolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/secret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/serviceperreplica.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/core-dns/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/core-dns/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-api-server/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/endpoints.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-dns/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-dns/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/endpoints.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/endpoints.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/endpoints.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-state-metrics/validate.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kubelet/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/node-exporter/validate.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/extra-objects.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/configmap-dashboards.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/configmaps-datasources.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/alertmanager-overview.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/apiserver.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/cluster-total.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/controller-manager.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/etcd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/grafana-overview.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-coredns.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-node.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/kubelet.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-pod.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-workload.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/node-rsrc-use.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/nodes-darwin.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/nodes.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/pod-total.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/prometheus.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/scheduler.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/workload-total.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/namespaces.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/_prometheus-operator.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/aggregate-clusterroles.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/certmanager.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/ciliumnetworkpolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/deployment.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/networkpolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp-clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp-clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/verticalpodautoscaler.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/_rules.tpl delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalAlertRelabelConfigs.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalAlertmanagerConfigs.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalPrometheusRules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalScrapeConfigs.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ciliumnetworkpolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/csi-secret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/extrasecret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingress.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingressThanosSidecar.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingressperreplica.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/networkpolicy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/nginx-config.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/podDisruptionBudget.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/podmonitors.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/prometheus.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp-clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp-clusterrolebinding.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/alertmanager.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/config-reloaders.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/etcd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/general.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-state-metrics.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubelet.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-apps.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-resources.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-storage.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-exporter.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-exporter.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-network.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/prometheus-operator.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/prometheus.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/windows.node.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/windows.pod.rules.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/secret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceThanosSidecar.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceThanosSidecarExternal.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitorThanosSidecar.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitors.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceperreplica.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/clusterrole.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/config-role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboard-role.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentbit-dashboard.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentd-dashboard.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/hardened.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/configmap.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/job.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/rbac.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/extrasecret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/ingress.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/podDisruptionBudget.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/ruler.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/secret.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/service.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/serviceaccount.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/servicemonitor.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/validate-install-crd.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/validate-psp-install.yaml delete mode 100644 charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/values.yaml diff --git a/assets/rancher-monitoring/rancher-monitoring-105.1.0-rc.1+up61.3.2.tgz b/assets/rancher-monitoring/rancher-monitoring-105.1.0-rc.1+up61.3.2.tgz deleted file mode 100644 index 5b5207b2a05d2b7b071392cb6832b4d2c071a8a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488466 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
SAmSe_vhEIST2kB${T)uZ~yQT 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

Okj%mrmu>22Dqk=Z}pP(jaDc0K! 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 z z5V;Le`?gc}60Adb%A~&U7}Y7l`@K0M(0Y-rpKa4NyHYiqNi;)>B6K zk-w5zbmA{elb@!Cb5Gtp$SX-pzn8^K(F3ICOfVaWVy3-=PZj|6HKzaRYgk0~qmL*+ zeGMfN#68RC~ZLPg@g z3fcB0qP)iGtD%NrGx@6gpuQ$o*L3JVeN6;6`Wmu$e_f~6L5b6*K*h+{*dm9k2CMIX zQNqZXN(YK^W`A4BcJFq}^Go}l%sdJ~qHW%2yi`a8Ryjd24Dgns*Y>Mz;x*?PC_Bw= zsc`p&!uFwBQpg=i!t|IJa1B@dkvOG~YFbTaU5dz`m~6A_fQ6h~#x&2NsOu4lV_b(a z#hftE7$T?+!*(!Qu6HfReS}^94=@w-KY`Mg09Icdg)@K^k;iiO4 z;ʃ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

&k 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 z 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

Seb4WfUb0LW*9`U2(CO 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 JK&Zq){uett#vT9w diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/.editorconfig b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/.editorconfig deleted file mode 100644 index f5ee2f4610..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -root = true - -[files/dashboards/*.json] -indent_size = 2 -indent_style = space \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/.helmignore deleted file mode 100644 index 9bdbec92b4..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/.helmignore +++ /dev/null @@ -1,29 +0,0 @@ -# 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 -# helm/charts -OWNERS -hack/ -ci/ -kube-prometheus-*.tgz - -unittests/ -files/dashboards/ diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/CHANGELOG.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/CHANGELOG.md deleted file mode 100644 index 8178169b91..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/CHANGELOG.md +++ /dev/null @@ -1,47 +0,0 @@ -# Changelog -All notable changes from the upstream Prometheus Operator chart will be added to this file. - -## [Package Version 00] - 2020-07-19 -### Added -- Added [Prometheus Adapter](https://github.com/helm/charts/tree/master/stable/prometheus-adapter) as a dependency to the upstream Prometheus Operator chart to allow users to expose custom metrics from the default Prometheus instance deployed by this chart -- Remove `prometheus-operator/cleanup-crds.yaml` and `prometheus-operator/crds.yaml` from the Prometheus Operator upstream chart in favor of just using the CRD directory to install the CRDs. -- Added support for `rkeControllerManager`, `rkeScheduler`, `rkeProxy`, and `rkeEtcd` PushProx exporters for monitoring k8s components within RKE clusters -- Added support for a `k3sServer` PushProx exporter that monitors k3s server components (`kubeControllerManager`, `kubeScheduler`, and `kubeProxy`) within k3s clusters -- Added support for `kubeAdmControllerManager`, `kubeAdmScheduler`, `kubeAdmProxy`, and `kubeAdmEtcd` PushProx exporters for monitoring k8s components within kubeAdm clusters -- Added support for `rke2ControllerManager`, `rke2Scheduler`, `rke2Proxy`, and `rke2Etcd` PushProx exporters for monitoring k8s components within rke2 clusters -- Exposed `prometheus.prometheusSpec.ignoreNamespaceSelectors` on values.yaml and set it to `false` by default. This value instructs the default Prometheus server deployed with this chart to ignore the `namespaceSelector` field within any created ServiceMonitor or PodMonitor CRs that it selects. This prevents ServiceMonitors and PodMonitors from configuring the Prometheus scrape configuration to monitor resources outside the namespace that they are deployed in; if a user needs to have one ServiceMonitor / PodMonitor monitor resources within several namespaces (such as the resources that are used to monitor Istio in a default installation), they should not enable this option since it would require them to create one ServiceMonitor / PodMonitor CR per namespace that they would like to monitor. Relevant fields were also updated in the default README.md. -- Added `grafana.sidecar.dashboards.searchNamespace` to `values.yaml` with a default value of `cattle-dashboards`. The namespace provided should contain all ConfigMaps with the label `grafana_dashboard` and will be searched by the Grafana Dashboards sidecar for updates. The namespace specified is also created along with this deployment. All default dashboard ConfigMaps have been relocated from the deployment namespace to the namespace specified -- Added `monitoring-admin`, `monitoring-edit`, and `monitoring-view` default `ClusterRoles` to allow admins to assign roles to users to interact with Prometheus Operator CRs. These can be enabled by setting `.Values.global.rbac.userRoles.create` (default: `true`). In a typical RBAC setup, you might want to use a `ClusterRoleBinding` to bind these roles to a Subject to allow them to set up or view `ServiceMonitors` / `PodMonitors` / `PrometheusRules` and view `Prometheus` or `Alertmanager` CRs across the cluster. If `.Values.global.rbac.userRoles.aggregateRolesForRBAC` is enabled, these ClusterRoles will aggregate into the respective default ClusterRoles provided by Kubernetes -- Added `monitoring-config-admin`, `monitoring-config-edit` and `monitoring-config-view` default `Roles` to allow admins to assign roles to users to be able to edit / view `Secrets` and `ConfigMaps` within the `cattle-monitoring-system` namespace. These can be enabled by setting `.Values.global.rbac.userRoles.create` (default: `true`). In a typical RBAC setup, you might want to use a `RoleBinding` to bind these roles to a Subject within the `cattle-monitoring-system` namespace to allow them to modify Secrets / ConfigMaps tied to the deployment, such as your Alertmanager Config Secret. -- Added `monitoring-dashboard-admin`, `monitoring-dashboard-edit` and `monitoring-dashboard-view` default `Roles` to allow admins to assign roles to users to be able to edit / view `ConfigMaps` within the `cattle-dashboards` namespace. These can be enabled by setting `.Values.global.rbac.userRoles.create` (default: `true`) and deploying Grafana as part of this chart. In a typical RBAC setup, you might want to use a `RoleBinding` to bind these roles to a Subject within the `cattle-dashboards` namespace to allow them to create / modify ConfigMaps that contain the JSON used to persist Grafana Dashboards on the cluster. -- Added default resource limits for `Prometheus Operator`, `Prometheus`, `AlertManager`, `Grafana`, `kube-state-metrics`, `node-exporter` -- Added a default template `rancher_defaults.tmpl` to AlertManager that Rancher will offer to users in order to help configure the way alerts are rendered on a notifier. Also updated the default template deployed with this chart to reference that template and added an example of a Slack config using this template as a comment in the `values.yaml`. -- Added support for private registries via introducing a new field for `global.cattle.systemDefaultRegistry` that, if supplied, will automatically be prepended onto every image used by the chart. -- Added a default `nginx` proxy container deployed with Grafana whose config is set in the `ConfigMap` located in `charts/grafana/templates/nginx-config.yaml`. The purpose of this container is to make it possible to view Grafana's UI through a proxy that has a subpath (e.g. Rancher's proxy). This proxy container is set to listen on port `8080` (with a `portName` of `nginx-http` instead of the default `service`), which is also where the Grafana service will now point to, and will forward all requests to the Grafana container listening on the default port `3000`. -- Added a default `nginx` proxy container deployed with Prometheus whose config is set in the `ConfigMap` located in `templates/prometheus/nginx-config.yaml`. The purpose of this container is to make it possible to view Prometheus's UI through a proxy that has a subpath (e.g. Rancher's proxy). This proxy container is set to listen on port `8081` (with a `portName` of `nginx-http` instead of the default `web`), which is also where the Prometheus service will now point to, and will forward all requests to the Prometheus container listening on the default port `9090`. -- Added support for passing CIS Scans in a hardened cluster by introducing a Job that patches the default service account within the `cattle-monitoring-system` and `cattle-dashboards` namespaces on install or upgrade and adding a default allow all `NetworkPolicy` to the `cattle-monitoring-system` and `cattle-dashboards` namespaces. -### Modified -- Updated the chart name from `prometheus-operator` to `rancher-monitoring` and added the `io.rancher.certified: rancher` annotation to `Chart.yaml` -- Modified the default `node-exporter` port from `9100` to `9796` -- Modified the default `nameOverride` to `rancher-monitoring`. This change is necessary as the Prometheus Adapter's default URL (`http://{{ .Values.nameOverride }}-prometheus.{{ .Values.namespaceOverride }}.svc`) is based off of the value used here; if modified, the default Adapter URL must also be modified -- Modified the default `namespaceOverride` to `cattle-monitoring-system`. This change is necessary as the Prometheus Adapter's default URL (`http://{{ .Values.nameOverride }}-prometheus.{{ .Values.namespaceOverride }}.svc`) is based off of the value used here; if modified, the default Adapter URL must also be modified -- Configured some default values for `grafana.service` values and exposed them in the default README.md -- The default namespaces the following ServiceMonitors were changed from the deployment namespace to allow them to continue to monitor metrics when `prometheus.prometheusSpec.ignoreNamespaceSelectors` is enabled: - - `core-dns`: `kube-system` - - `api-server`: `default` - - `kube-controller-manager`: `kube-system` - - `kubelet`: `{{ .Values.kubelet.namespace }}` -- Disabled the following deployments by default (can be enabled if required): - - `AlertManager` - - `kube-controller-manager` metrics exporter - - `kube-etcd` metrics exporter - - `kube-scheduler` metrics exporter - - `kube-proxy` metrics exporter -- Updated default Grafana `deploymentStrategy` to `Recreate` to prevent deployments from being stuck on upgrade if a PV is attached to Grafana -- Modified the default `SelectorNilUsesHelmValues` to default to `false`. As a result, we look for all CRs with any labels in all namespaces by default rather than just the ones tagged with the label `release: rancher-monitoring`. -- Modified the default images used by the `rancher-monitoring` chart to point to Rancher mirrors of the original images from upstream. -- Modified the behavior of the chart to create the Alertmanager Config Secret via a pre-install hook instead of using the normal Helm lifecycle to manage the secret. The benefit of this approach is that all changes to the Config Secret done on a live cluster will never get overridden on a `helm upgrade` since the secret only gets created on a `helm install`. If you would like the secret to be cleaned up on an `helm uninstall`, enable `alertmanager.cleanupOnUninstall`; however, this is disabled by default to prevent the loss of alerting configuration on an uninstall. This secret will never be modified on a `helm upgrade`. -- Modified the default `securityContext` for `Pod` templates across the chart to `{"runAsNonRoot": "true", "runAsUser": "1000"}` and replaced `grafana.rbac.pspUseAppArmor` in favor of `grafana.rbac.pspAnnotations={}` in order to make it possible to deploy this chart on a hardened cluster which does not support Seccomp or AppArmor annotations in PSPs. Users can always choose to specify the annotations they want to use for the PSP directly as part of the values provided. -- Modified `.Values.prometheus.prometheusSpec.containers` to take in a string representing a template that should be rendered by Helm (via `tpl`) instead of allowing a user to provide YAML directly. -- Modified the default Grafana configuration to auto assign users who access Grafana to the Viewer role and enable anonymous access to Grafana dashboards by default. This default works well for a Rancher user who is accessing Grafana via the `kubectl proxy` on the Rancher Dashboard UI since anonymous users who enter via the proxy are authenticated by the k8s API Server, but you can / should modify this behavior if you plan on exposing Grafana in a way that does not require authentication (e.g. as a `NodePort` service). -- Modified the default Grafana configuration to add a default dashboard for Rancher on the Grafana home page. \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/CONTRIBUTING.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/CONTRIBUTING.md deleted file mode 100644 index f6ce2a3235..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/CONTRIBUTING.md +++ /dev/null @@ -1,12 +0,0 @@ -# Contributing Guidelines - -## How to contribute to this chart - -1. Fork this repository, develop and test your Chart. -1. Bump the chart version for every change. -1. Ensure PR title has the prefix `[kube-prometheus-stack]` -1. When making changes to rules or dashboards, see the README.md section on how to sync data from upstream repositories -1. Check the `hack/minikube` folder has scripts to set up minikube and components of this chart that will allow all components to be scraped. You can use this configuration when validating your changes. -1. Check for changes of RBAC rules. -1. Check for changes in CRD specs. -1. PR must pass the linter (`helm lint`) diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/Chart.yaml deleted file mode 100644 index 5258903e1f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/Chart.yaml +++ /dev/null @@ -1,126 +0,0 @@ -annotations: - artifacthub.io/license: Apache-2.0 - artifacthub.io/links: | - - name: Chart Source - url: https://github.com/prometheus-community/helm-charts - - name: Upstream Project - url: https://github.com/prometheus-operator/kube-prometheus - artifacthub.io/operator: "true" - catalog.cattle.io/auto-install: rancher-monitoring-crd=match - catalog.cattle.io/certified: rancher - catalog.cattle.io/deploys-on-os: windows - catalog.cattle.io/display-name: Monitoring - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/namespace: cattle-monitoring-system - catalog.cattle.io/permits-os: linux,windows - catalog.cattle.io/provides-gvr: monitoring.coreos.com.prometheus/v1 - catalog.cattle.io/rancher-version: '>= 2.9.0-0 < 2.10.0-0' - catalog.cattle.io/release-name: rancher-monitoring - catalog.cattle.io/requests-cpu: 4500m - catalog.cattle.io/requests-memory: 4000Mi - catalog.cattle.io/type: cluster-tool - catalog.cattle.io/ui-component: monitoring - catalog.cattle.io/upstream-version: 57.0.3 -apiVersion: v2 -appVersion: v0.75.1 -dependencies: -- condition: grafana.enabled - name: grafana - repository: file://./charts/grafana -- condition: hardenedKubelet.enabled - name: hardenedKubelet - repository: file://./charts/hardenedKubelet -- condition: hardenedNodeExporter.enabled - name: hardenedNodeExporter - repository: file://./charts/hardenedNodeExporter -- condition: k3sServer.enabled - name: k3sServer - repository: file://./charts/k3sServer -- condition: kubeStateMetrics.enabled - name: kube-state-metrics - repository: file://./charts/kube-state-metrics -- condition: kubeAdmControllerManager.enabled - name: kubeAdmControllerManager - repository: file://./charts/kubeAdmControllerManager -- condition: kubeAdmEtcd.enabled - name: kubeAdmEtcd - repository: file://./charts/kubeAdmEtcd -- condition: kubeAdmProxy.enabled - name: kubeAdmProxy - repository: file://./charts/kubeAdmProxy -- condition: kubeAdmScheduler.enabled - name: kubeAdmScheduler - repository: file://./charts/kubeAdmScheduler -- condition: prometheus-adapter.enabled - name: prometheus-adapter - repository: file://./charts/prometheus-adapter -- condition: nodeExporter.enabled - name: prometheus-node-exporter - repository: file://./charts/prometheus-node-exporter -- condition: rke2ControllerManager.enabled - name: rke2ControllerManager - repository: file://./charts/rke2ControllerManager -- condition: rke2Etcd.enabled - name: rke2Etcd - repository: file://./charts/rke2Etcd -- condition: rke2IngressNginx.enabled - name: rke2IngressNginx - repository: file://./charts/rke2IngressNginx -- condition: rke2Proxy.enabled - name: rke2Proxy - repository: file://./charts/rke2Proxy -- condition: rke2Scheduler.enabled - name: rke2Scheduler - repository: file://./charts/rke2Scheduler -- condition: rkeControllerManager.enabled - name: rkeControllerManager - repository: file://./charts/rkeControllerManager -- condition: rkeEtcd.enabled - name: rkeEtcd - repository: file://./charts/rkeEtcd -- condition: rkeIngressNginx.enabled - name: rkeIngressNginx - repository: file://./charts/rkeIngressNginx -- condition: rkeProxy.enabled - name: rkeProxy - repository: file://./charts/rkeProxy -- condition: rkeScheduler.enabled - name: rkeScheduler - repository: file://./charts/rkeScheduler -- condition: windowsExporter.enabled - name: windowsExporter - repository: file://./charts/windowsExporter -description: kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards, - and Prometheus rules combined with documentation and scripts to provide easy to - operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus - Operator. -home: https://github.com/prometheus-operator/kube-prometheus -icon: file://assets/logos/rancher-monitoring.png -keywords: -- operator -- prometheus -- kube-prometheus -kubeVersion: '>=1.28.0-0' -maintainers: -- email: andrew@quadcorps.co.uk - name: andrewgkew -- email: gianrubio@gmail.com - name: gianrubio -- email: github.gkarthiks@gmail.com - name: gkarthiks -- email: kube-prometheus-stack@sisti.pt - name: GMartinez-Sisti -- email: github@jkroepke.de - name: jkroepke -- email: scott@r6by.com - name: scottrigby -- email: miroslav.hadzhiev@gmail.com - name: Xtigyro -- email: quentin.bisson@gmail.com - name: QuentinBisson -name: rancher-monitoring -sources: -- https://github.com/prometheus-community/helm-charts -- https://github.com/prometheus-operator/kube-prometheus -type: application -version: 105.1.0-rc.1+up61.3.2 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/README.md deleted file mode 100644 index 46f751587e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/README.md +++ /dev/null @@ -1,1140 +0,0 @@ -# kube-prometheus-stack - -Installs the [kube-prometheus stack](https://github.com/prometheus-operator/kube-prometheus), a collection of Kubernetes manifests, [Grafana](http://grafana.com/) dashboards, and [Prometheus rules](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with [Prometheus](https://prometheus.io/) using the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator). - -See the [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) README for details about components, dashboards, and alerts. - -_Note: This chart was formerly named `prometheus-operator` chart, now renamed to more clearly reflect that it installs the `kube-prometheus` project stack, within which Prometheus Operator is only one component._ - -## Prerequisites - -- Kubernetes 1.19+ -- Helm 3+ - -## Get Helm Repository Info - -```console -helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -helm repo update -``` - -_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ - -## Install Helm Chart - -```console -helm install [RELEASE_NAME] prometheus-community/kube-prometheus-stack -``` - -_See [configuration](#configuration) below._ - -_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ - -## Dependencies - -By default this chart installs additional, dependent charts: - -- [prometheus-community/kube-state-metrics](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics) -- [prometheus-community/prometheus-node-exporter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-node-exporter) -- [grafana/grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana) - -To disable dependencies during installation, see [multiple releases](#multiple-releases) below. - -_See [helm dependency](https://helm.sh/docs/helm/helm_dependency/) for command documentation._ - -## 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._ - -CRDs created by this chart are not removed by default and should be manually cleaned up: - -```console -kubectl delete crd alertmanagerconfigs.monitoring.coreos.com -kubectl delete crd alertmanagers.monitoring.coreos.com -kubectl delete crd podmonitors.monitoring.coreos.com -kubectl delete crd probes.monitoring.coreos.com -kubectl delete crd prometheusagents.monitoring.coreos.com -kubectl delete crd prometheuses.monitoring.coreos.com -kubectl delete crd prometheusrules.monitoring.coreos.com -kubectl delete crd scrapeconfigs.monitoring.coreos.com -kubectl delete crd servicemonitors.monitoring.coreos.com -kubectl delete crd thanosrulers.monitoring.coreos.com -``` - -## Upgrading Chart - -```console -helm upgrade [RELEASE_NAME] prometheus-community/kube-prometheus-stack -``` - -With Helm v3, CRDs created by this chart are not updated by default and should be manually updated. -Consult also the [Helm Documentation on CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions). - -_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ - -### 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. - -### From 60.x to 61.x - -This version upgrades Prometheus-Operator to v0.75.0 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 59.x to 60.x - -This version upgrades the Grafana chart to v8.0.x which introduces Grafana 11. This new major version of Grafana contains some breaking changes described in [Breaking changes in Grafana v11.0](https://grafana.com/docs/grafana/latest/breaking-changes/breaking-changes-v11-0/). - -### From 58.x to 59.x - -This version upgrades Prometheus-Operator to v0.74.0 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 57.x to 58.x - -This version upgrades Prometheus-Operator to v0.73.0 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 56.x to 57.x - -This version upgrades Prometheus-Operator to v0.72.0 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 55.x to 56.x - -This version upgrades Prometheus-Operator to v0.71.0, Prometheus to 2.49.1 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 54.x to 55.x - -This version upgrades Prometheus-Operator to v0.70.0 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 53.x to 54.x - -Grafana Helm Chart has bumped to version 7 - -Please note Grafana Helm Chart [changelog](https://github.com/grafana/helm-charts/tree/main/charts/grafana#to-700). - -### From 52.x to 53.x - -This version upgrades Prometheus-Operator to v0.69.1, Prometheus to 2.47.2 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 51.x to 52.x - -This includes the ability to select between using existing secrets or create new secret objects for various thanos config. The defaults have not changed but if you were setting: - -- `thanosRuler.thanosRulerSpec.alertmanagersConfig` or -- `thanosRuler.thanosRulerSpec.objectStorageConfig` or -- `thanosRuler.thanosRulerSpec.queryConfig` or -- `prometheus.prometheusSpec.thanos.objectStorageConfig` - -you will have to need to set `existingSecret` or `secret` based on your requirement - -For instance, the `thanosRuler.thanosRulerSpec.alertmanagersConfig` used to be configured as follow: - -```yaml -thanosRuler: - thanosRulerSpec: - alertmanagersConfig: - alertmanagers: - - api_version: v2 - http_config: - basic_auth: - username: some_user - password: some_pass - static_configs: - - alertmanager.thanos.io - scheme: http - timeout: 10s -``` - -But it now moved to: - -```yaml -thanosRuler: - thanosRulerSpec: - alertmanagersConfig: - secret: - alertmanagers: - - api_version: v2 - http_config: - basic_auth: - username: some_user - password: some_pass - static_configs: - - alertmanager.thanos.io - scheme: http - timeout: 10s -``` - -or the `thanosRuler.thanosRulerSpec.objectStorageConfig` used to be configured as follow: - -```yaml -thanosRuler: - thanosRulerSpec: - objectStorageConfig: - name: existing-secret-not-created-by-this-chart - key: object-storage-configs.yaml -``` - -But it now moved to: - -```yaml -thanosRuler: - thanosRulerSpec: - objectStorageConfig: - existingSecret: - name: existing-secret-not-created-by-this-chart - key: object-storage-configs.yaml -``` - -### From 50.x to 51.x - -This version upgrades Prometheus-Operator to v0.68.0, Prometheus to 2.47.0 and Thanos to v0.32.2 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 49.x to 50.x - -This version requires Kubernetes 1.19+. - -We do not expect any breaking changes in this version. - -### From 48.x to 49.x - -This version upgrades Prometheus-Operator to v0.67.1, 0, Alertmanager to v0.26.0, Prometheus to 2.46.0 and Thanos to v0.32.0 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 47.x to 48.x - -This version moved all CRDs into a dedicated sub-chart. No new CRDs are introduced in this version. -See [#3548](https://github.com/prometheus-community/helm-charts/issues/3548) for more context. - -We do not expect any breaking changes in this version. - -### From 46.x to 47.x - -This version upgrades Prometheus-Operator to v0.66.0 with new CRDs (PrometheusAgent and ScrapeConfig). - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 45.x to 46.x - -This version upgrades Prometheus-Operator to v0.65.1 with new CRDs (PrometheusAgent and ScrapeConfig), Prometheus to v2.44.0 and Thanos to v0.31.0. - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 44.x to 45.x - -This version upgrades Prometheus-Operator to v0.63.0, Prometheus to v2.42.0 and Thanos to v0.30.2. - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 43.x to 44.x - -This version upgrades Prometheus-Operator to v0.62.0, Prometheus to v2.41.0 and Thanos to v0.30.1. - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -If you have explicitly set `prometheusOperator.admissionWebhooks.failurePolicy`, this value is now always used even when `.prometheusOperator.admissionWebhooks.patch.enabled` is `true` (the default). - -The values for `prometheusOperator.image.tag` & `prometheusOperator.prometheusConfigReloader.image.tag` are now empty by default and the Chart.yaml `appVersion` field is used instead. - -### From 42.x to 43.x - -This version upgrades Prometheus-Operator to v0.61.1, Prometheus to v2.40.5 and Thanos to v0.29.0. - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 41.x to 42.x - -This includes the overridability of container registry for all containers at the global level using `global.imageRegistry` or per container image. The defaults have not changed but if you were using a custom image, you will have to override the registry of said custom container image before you upgrade. - -For instance, the prometheus-config-reloader used to be configured as follow: - -```yaml - image: - repository: quay.io/prometheus-operator/prometheus-config-reloader - tag: v0.60.1 - sha: "" -``` - -But it now moved to: - -```yaml - image: - registry: quay.io - repository: prometheus-operator/prometheus-config-reloader - tag: v0.60.1 - sha: "" -``` - -### From 40.x to 41.x - -This version upgrades Prometheus-Operator to v0.60.1, Prometheus to v2.39.1 and Thanos to v0.28.1. -This version also upgrades the Helm charts of kube-state-metrics to 4.20.2, prometheus-node-exporter to 4.3.0 and Grafana to 6.40.4. - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -This version splits kubeScheduler recording and altering rules in separate config values. -Instead of `defaultRules.rules.kubeScheduler` the 2 new variables `defaultRules.rules.kubeSchedulerAlerting` and `defaultRules.rules.kubeSchedulerRecording` are used. - -### From 39.x to 40.x - -This version upgrades Prometheus-Operator to v0.59.1, Prometheus to v2.38.0, kube-state-metrics to v2.6.0 and Thanos to v0.28.0. -This version also upgrades the Helm charts of kube-state-metrics to 4.18.0 and prometheus-node-exporter to 4.2.0. - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -Starting from prometheus-node-exporter version 4.0.0, the `node exporter` chart is using the [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/). Therefore you have to delete the daemonset before you upgrade. - -```console -kubectl delete daemonset -l app=prometheus-node-exporter -helm upgrade -i kube-prometheus-stack prometheus-community/kube-prometheus-stack -``` - -If you use your own custom [ServiceMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor) or [PodMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#podmonitor), please ensure to upgrade their `selector` fields accordingly to the new labels. - -### From 38.x to 39.x - -This upgraded prometheus-operator to v0.58.0 and prometheus to v2.37.0 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 37.x to 38.x - -Reverted one of the default metrics relabelings for cAdvisor added in 36.x, due to it breaking container_network_* and various other statistics. If you do not want this change, you will need to override the `kubelet.cAdvisorMetricRelabelings`. - -### From 36.x to 37.x - -This includes some default metric relabelings for cAdvisor and apiserver metrics to reduce cardinality. If you do not want these defaults, you will need to override the `kubeApiServer.metricRelabelings` and or `kubelet.cAdvisorMetricRelabelings`. - -### From 35.x to 36.x - -This upgraded prometheus-operator to v0.57.0 and prometheus to v2.36.1 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 34.x to 35.x - -This upgraded prometheus-operator to v0.56.0 and prometheus to v2.35.0 - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 33.x to 34.x - -This upgrades to prometheus-operator to v0.55.0 and prometheus to v2.33.5. - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 32.x to 33.x - -This upgrades the prometheus-node-exporter Chart to v3.0.0. Please review the changes to this subchart if you make customizations to hostMountPropagation. - -### From 31.x to 32.x - -This upgrades to prometheus-operator to v0.54.0 and prometheus to v2.33.1. It also changes the default for `grafana.serviceMonitor.enabled` to `true. - -Run these commands to update the CRDs before applying the upgrade. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 30.x to 31.x - -This version removes the built-in grafana ServiceMonitor and instead relies on the ServiceMonitor of the sub-chart. -`grafana.serviceMonitor.enabled` must be set instead of `grafana.serviceMonitor.selfMonitor` and the old ServiceMonitor may -need to be manually cleaned up after deploying the new release. - -### From 29.x to 30.x - -This version updates kube-state-metrics to 4.3.0 and uses the new option `kube-state-metrics.releaseLabel=true` which adds the "release" label to kube-state-metrics labels, making scraping of the metrics by kube-prometheus-stack work out of the box again, independent of the used kube-prometheus-stack release name. If you already set the "release" label via `kube-state-metrics.customLabels` you might have to remove that and use it via the new option. - -### From 28.x to 29.x - -This version makes scraping port for kube-controller-manager and kube-scheduler dynamic to reflect changes to default serving ports -for those components in Kubernetes versions v1.22 and v1.23 respectively. - -If you deploy on clusters using version v1.22+, kube-controller-manager will be scraped over HTTPS on port 10257. - -If you deploy on clusters running version v1.23+, kube-scheduler will be scraped over HTTPS on port 10259. - -### From 27.x to 28.x - -This version disables PodSecurityPolicies by default because they are deprecated in Kubernetes 1.21 and will be removed in Kubernetes 1.25. - -If you are using PodSecurityPolicies you can enable the previous behaviour by setting `kube-state-metrics.podSecurityPolicy.enabled`, `prometheus-node-exporter.rbac.pspEnabled`, `grafana.rbac.pspEnabled` and `global.rbac.pspEnabled` to `true`. - -### From 26.x to 27.x - -This version splits prometheus-node-exporter chart recording and altering rules in separate config values. -Instead of `defaultRules.rules.node` the 2 new variables `defaultRules.rules.nodeExporterAlerting` and `defaultRules.rules.nodeExporterRecording` are used. - -Also the following defaultRules.rules has been removed as they had no effect: `kubeApiserverError`, `kubePrometheusNodeAlerting`, `kubernetesAbsent`, `time`. - -The ability to set a rubookUrl via `defaultRules.rules.rubookUrl` was reintroduced. - -### From 25.x to 26.x - -This version enables the prometheus-node-exporter subchart servicemonitor by default again, by setting `prometheus-node-exporter.prometheus.monitor.enabled` to `true`. - -### From 24.x to 25.x - -This version upgrade to prometheus-operator v0.53.1. It removes support for setting a runbookUrl, since the upstream format for runbooks changed. - -```console -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 23.x to 24.x - -The custom `ServiceMonitor` for the _kube-state-metrics_ & _prometheus-node-exporter_ charts have been removed in favour of the built-in sub-chart `ServiceMonitor`; for both sub-charts this means that `ServiceMonitor` customisations happen via the values passed to the chart. If you haven't directly customised this behaviour then there are no changes required to upgrade, but if you have please read the following. - -For _kube-state-metrics_ the `ServiceMonitor` customisation is now set via `kube-state-metrics.prometheus.monitor` and the `kubeStateMetrics.serviceMonitor.selfMonitor.enabled` value has moved to `kube-state-metrics.selfMonitor.enabled`. - -For _prometheus-node-exporter_ the `ServiceMonitor` customisation is now set via `prometheus-node-exporter.prometheus.monitor` and the `nodeExporter.jobLabel` values has moved to `prometheus-node-exporter.prometheus.monitor.jobLabel`. - -### From 22.x to 23.x - -Port names have been renamed for Istio's -[explicit protocol selection](https://istio.io/latest/docs/ops/configuration/traffic-management/protocol-selection/#explicit-protocol-selection). - -| | old value | new value | -|-|-----------|-----------| -| `alertmanager.alertmanagerSpec.portName` | `web` | `http-web` | -| `grafana.service.portName` | `service` | `http-web` | -| `prometheus-node-exporter.service.portName` | `metrics` (hardcoded) | `http-metrics` | -| `prometheus.prometheusSpec.portName` | `web` | `http-web` | - -### From 21.x to 22.x - -Due to the upgrade of the `kube-state-metrics` chart, removal of its deployment/stateful needs to done manually prior to upgrading: - -```console -kubectl delete deployments.apps -l app.kubernetes.io/instance=prometheus-operator,app.kubernetes.io/name=kube-state-metrics --cascade=orphan -``` - -or if you use autosharding: - -```console -kubectl delete statefulsets.apps -l app.kubernetes.io/instance=prometheus-operator,app.kubernetes.io/name=kube-state-metrics --cascade=orphan -``` - -### From 20.x to 21.x - -The config reloader values have been refactored. All the values have been moved to the key `prometheusConfigReloader` and the limits and requests can now be set separately. - -### From 19.x to 20.x - -Version 20 upgrades prometheus-operator from 0.50.x to 0.52.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 18.x to 19.x - -`kubeStateMetrics.serviceMonitor.namespaceOverride` was removed. -Please use `kube-state-metrics.namespaceOverride` instead. - -### From 17.x to 18.x - -Version 18 upgrades prometheus-operator from 0.49.x to 0.50.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 16.x to 17.x - -Version 17 upgrades prometheus-operator from 0.48.x to 0.49.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 15.x to 16.x - -Version 16 upgrades kube-state-metrics to v2.0.0. This includes changed command-line arguments and removed metrics, see this [blog post](https://kubernetes.io/blog/2021/04/13/kube-state-metrics-v-2-0/). This version also removes Grafana dashboards that supported Kubernetes 1.14 or earlier. - -### From 14.x to 15.x - -Version 15 upgrades prometheus-operator from 0.46.x to 0.47.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 13.x to 14.x - -Version 14 upgrades prometheus-operator from 0.45.x to 0.46.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml -``` - -### From 12.x to 13.x - -Version 13 upgrades prometheus-operator from 0.44.x to 0.45.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRD manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.45.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.45.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.45.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml -``` - -### From 11.x to 12.x - -Version 12 upgrades prometheus-operator from 0.43.x to 0.44.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRD manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/release-0.44/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml -``` - -The chart was migrated to support only helm v3 and later. - -### From 10.x to 11.x - -Version 11 upgrades prometheus-operator from 0.42.x to 0.43.x. Starting with 0.43.x an additional `AlertmanagerConfigs` CRD is introduced. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRD manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/release-0.43/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml -``` - -Version 11 removes the deprecated tlsProxy via ghostunnel in favor of native TLS support the prometheus-operator gained with v0.39.0. - -### From 9.x to 10.x - -Version 10 upgrades prometheus-operator from 0.38.x to 0.42.x. Starting with 0.40.x an additional `Probes` CRD is introduced. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRD manually before updating: - -```console -kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/release-0.42/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml -``` - -### From 8.x to 9.x - -Version 9 of the helm chart removes the existing `additionalScrapeConfigsExternal` in favour of `additionalScrapeConfigsSecret`. This change lets users specify the secret name and secret key to use for the additional scrape configuration of prometheus. This is useful for users that have prometheus-operator as a subchart and also have a template that creates the additional scrape configuration. - -### From 7.x to 8.x - -Due to new template functions being used in the rules in version 8.x.x of the chart, an upgrade to Prometheus Operator and Prometheus is necessary in order to support them. First, upgrade to the latest version of 7.x.x - -```console -helm upgrade [RELEASE_NAME] prometheus-community/kube-prometheus-stack --version 7.5.0 -``` - -Then upgrade to 8.x.x - -```console -helm upgrade [RELEASE_NAME] prometheus-community/kube-prometheus-stack --version [8.x.x] -``` - -Minimal recommended Prometheus version for this chart release is `2.12.x` - -### From 6.x to 7.x - -Due to a change in grafana subchart, version 7.x.x now requires Helm >= 2.12.0. - -### From 5.x to 6.x - -Due to a change in deployment labels of kube-state-metrics, the upgrade requires `helm upgrade --force` in order to re-create the deployment. If this is not done an error will occur indicating that the deployment cannot be modified: - -```console -invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/name":"kube-state-metrics"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable -``` - -If this error has already been encountered, a `helm history` command can be used to determine which release has worked, then `helm rollback` to the release, then `helm upgrade --force` to this new one - -## Configuration - -See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: - -```console -helm show values prometheus-community/kube-prometheus-stack -``` - -You may also run `helm show values` on this chart's [dependencies](#dependencies) for additional options. - -### Rancher Monitoring Configuration - -The following table shows values exposed by Rancher Monitoring's additions to the chart: - -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `nameOverride` | Provide a name that should be used instead of the chart name when naming all resources deployed by this chart |`"rancher-monitoring"`| -| `namespaceOverride` | Override the deployment namespace | `"cattle-monitoring-system"` | -| `global.rbac.userRoles.create` | Create default user ClusterRoles to allow users to interact with Prometheus CRs, ConfigMaps, and Secrets | `true` | -| `global.rbac.userRoles.aggregateToDefaultRoles` | Aggregate default user ClusterRoles into default k8s ClusterRoles | `true` | -| `prometheus-adapter.enabled` | Whether to install [prometheus-adapter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-adapter) within the cluster | `true` | -| `prometheus-adapter.prometheus.url` | A URL pointing to the Prometheus deployment within your cluster. The default value is set based on the assumption that you plan to deploy the default Prometheus instance from this chart where `.Values.namespaceOverride=cattle-monitoring-system` and `.Values.nameOverride=rancher-monitoring` | `http://rancher-monitoring-prometheus.cattle-monitoring-system.svc` | -| `prometheus-adapter.prometheus.port` | The port on the Prometheus deployment that Prometheus Adapter can make requests to | `9090` | -| `prometheus.prometheusSpec.ignoreNamespaceSelectors` | Ignore NamespaceSelector settings from the PodMonitor and ServiceMonitor configs. If true, PodMonitors and ServiceMonitors can only discover Pods and Services within the namespace they are deployed into | `false` | - -The following values are enabled for different distributions via [rancher-pushprox](https://github.com/rancher/dev-charts/tree/master/packages/rancher-pushprox). See the rancher-pushprox `README.md` for more information on what all values can be configured for the PushProxy chart. - -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `rkeControllerManager.enabled` | Create a PushProx installation for monitoring kube-controller-manager metrics in RKE clusters | `false` | -| `rkeScheduler.enabled` | Create a PushProx installation for monitoring kube-scheduler metrics in RKE clusters | `false` | -| `rkeProxy.enabled` | Create a PushProx installation for monitoring kube-proxy metrics in RKE clusters | `false` | -| `rkeIngressNginx.enabled` | Create a PushProx installation for monitoring ingress-nginx metrics in RKE clusters | `false` | -| `rkeEtcd.enabled` | Create a PushProx installation for monitoring etcd metrics in RKE clusters | `false` | -| `rke2IngressNginx.enabled` | Create a PushProx installation for monitoring ingress-nginx metrics in RKE2 clusters | `false` | -| `k3sServer.enabled` | Create a PushProx installation for monitoring k3s-server metrics (accounts for kube-controller-manager, kube-scheduler, and kube-proxy metrics) in k3s clusters | `false` | -| `kubeAdmControllerManager.enabled` | Create a PushProx installation for monitoring kube-controller-manager metrics in kubeAdm clusters | `false` | -| `kubeAdmScheduler.enabled` | Create a PushProx installation for monitoring kube-scheduler metrics in kubeAdm clusters | `false` | -| `kubeAdmProxy.enabled` | Create a PushProx installation for monitoring kube-proxy metrics in kubeAdm clusters | `false` | -| `kubeAdmEtcd.enabled` | Create a PushProx installation for monitoring etcd metrics in kubeAdm clusters | `false` | - -### Multiple releases - -The same chart can be used to run multiple Prometheus instances in the same cluster if required. To achieve this, it is necessary to run only one instance of prometheus-operator and a pair of alertmanager pods for an HA configuration, while all other components need to be disabled. To disable a dependency during installation, set `kubeStateMetrics.enabled`, `nodeExporter.enabled` and `grafana.enabled` to `false`. - -## Work-Arounds for Known Issues - -### Running on private GKE clusters - -When Google configure the control plane for private clusters, they automatically configure VPC peering between your Kubernetes cluster’s network and a separate Google managed project. In order to restrict what Google are able to access within your cluster, the firewall rules configured restrict access to your Kubernetes pods. This means that in order to use the webhook component with a GKE private cluster, you must configure an additional firewall rule to allow the GKE control plane access to your webhook pod. - -You can read more information on how to add firewall rules for the GKE control plane nodes in the [GKE docs](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#add_firewall_rules) - -Alternatively, you can disable the hooks by setting `prometheusOperator.admissionWebhooks.enabled=false`. - -## PrometheusRules Admission Webhooks - -With Prometheus Operator version 0.30+, the core Prometheus Operator pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent malformed rules from being added to the cluster. - -### How the Chart Configures the Hooks - -A validating and mutating webhook configuration requires the endpoint to which the request is sent to use TLS. It is possible to set up custom certificates to do this, but in most cases, a self-signed certificate is enough. The setup of this component requires some more complex orchestration when using helm. The steps are created to be idempotent and to allow turning the feature on and off without running into helm quirks. - -1. A pre-install hook provisions a certificate into the same namespace using a format compatible with provisioning using end user certificates. If the certificate already exists, the hook exits. -2. The prometheus operator pod is configured to use a TLS proxy container, which will load that certificate. -3. Validating and Mutating webhook configurations are created in the cluster, with their failure mode set to Ignore. This allows rules to be created by the same chart at the same time, even though the webhook has not yet been fully set up - it does not have the correct CA field set. -4. A post-install hook reads the CA from the secret created by step 1 and patches the Validating and Mutating webhook configurations. This process will allow a custom CA provisioned by some other process to also be patched into the webhook configurations. The chosen failure policy is also patched into the webhook configurations - -### Alternatives - -It should be possible to use [jetstack/cert-manager](https://github.com/jetstack/cert-manager) if a more complete solution is required, but it has not been tested. - -You can enable automatic self-signed TLS certificate provisioning via cert-manager by setting the `prometheusOperator.admissionWebhooks.certManager.enabled` value to true. - -### Limitations - -Because the operator can only run as a single pod, there is potential for this component failure to cause rule deployment failure. Because this risk is outweighed by the benefit of having validation, the feature is enabled by default. - -## Developing Prometheus Rules and Grafana Dashboards - -This chart Grafana Dashboards and Prometheus Rules are just a copy from [prometheus-operator/prometheus-operator](https://github.com/prometheus-operator/prometheus-operator) and other sources, synced (with alterations) by scripts in [hack](hack) folder. In order to introduce any changes you need to first [add them to the original repository](https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/customizations/developing-prometheus-rules-and-grafana-dashboards.md) and then sync there by scripts. - -## Further Information - -For more in-depth documentation of configuration options meanings, please see - -- [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator) -- [Prometheus](https://prometheus.io/docs/introduction/overview/) -- [Grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana#grafana-helm-chart) - -## prometheus.io/scrape - -The prometheus operator does not support annotation-based discovery of services, using the `PodMonitor` or `ServiceMonitor` CRD in its place as they provide far more configuration options. -For information on how to use PodMonitors/ServiceMonitors, please see the documentation on the `prometheus-operator/prometheus-operator` documentation here: - -- [ServiceMonitors](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md#include-servicemonitors) -- [PodMonitors](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md#include-podmonitors) -- [Running Exporters](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/running-exporters.md) - -By default, Prometheus discovers PodMonitors and ServiceMonitors within its namespace, that are labeled with the same release tag as the prometheus-operator release. -Sometimes, you may need to discover custom PodMonitors/ServiceMonitors, for example used to scrape data from third-party applications. -An easy way of doing this, without compromising the default PodMonitors/ServiceMonitors discovery, is allowing Prometheus to discover all PodMonitors/ServiceMonitors within its namespace, without applying label filtering. -To do so, you can set `prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues` and `prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues` to `false`. - -## Migrating from stable/prometheus-operator chart - -## Zero downtime - -Since `kube-prometheus-stack` is fully compatible with the `stable/prometheus-operator` chart, a migration without downtime can be achieved. -However, the old name prefix needs to be kept. If you want the new name please follow the step by step guide below (with downtime). - -You can override the name to achieve this: - -```console -helm upgrade prometheus-operator prometheus-community/kube-prometheus-stack -n monitoring --reuse-values --set nameOverride=prometheus-operator -``` - -**Note**: It is recommended to run this first with `--dry-run --debug`. - -## Redeploy with new name (downtime) - -If the **prometheus-operator** values are compatible with the new **kube-prometheus-stack** chart, please follow the below steps for migration: - -> The guide presumes that chart is deployed in `monitoring` namespace and the deployments are running there. If in other namespace, please replace the `monitoring` to the deployed namespace. - -1. Patch the PersistenceVolume created/used by the prometheus-operator chart to `Retain` claim policy: - - ```console - kubectl patch pv/ -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' - ``` - - **Note:** To execute the above command, the user must have a cluster wide permission. Please refer [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) - -2. Uninstall the **prometheus-operator** release and delete the existing PersistentVolumeClaim, and verify PV become Released. - - ```console - helm uninstall prometheus-operator -n monitoring - kubectl delete pvc/ -n monitoring - ``` - - Additionally, you have to manually remove the remaining `prometheus-operator-kubelet` service. - - ```console - kubectl delete service/prometheus-operator-kubelet -n kube-system - ``` - - You can choose to remove all your existing CRDs (ServiceMonitors, Podmonitors, etc.) if you want to. - -3. Remove current `spec.claimRef` values to change the PV's status from Released to Available. - - ```console - kubectl patch pv/ --type json -p='[{"op": "remove", "path": "/spec/claimRef"}]' -n monitoring - ``` - -**Note:** To execute the above command, the user must have a cluster wide permission. Please refer to [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) - -After these steps, proceed to a fresh **kube-prometheus-stack** installation and make sure the current release of **kube-prometheus-stack** matching the `volumeClaimTemplate` values in the `values.yaml`. - -The binding is done via matching a specific amount of storage requested and with certain access modes. - -For example, if you had storage specified as this with **prometheus-operator**: - -```yaml -volumeClaimTemplate: - spec: - storageClassName: gp2 - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: 50Gi -``` - -You have to specify matching `volumeClaimTemplate` with 50Gi storage and `ReadWriteOnce` access mode. - -Additionally, you should check the current AZ of your legacy installation's PV, and configure the fresh release to use the same AZ as the old one. If the pods are in a different AZ than the PV, the release will fail to bind the existing one, hence creating a new PV. - -This can be achieved either by specifying the labels through `values.yaml`, e.g. setting `prometheus.prometheusSpec.nodeSelector` to: - -```yaml -nodeSelector: - failure-domain.beta.kubernetes.io/zone: east-west-1a -``` - -or passing these values as `--set` overrides during installation. - -The new release should now re-attach your previously released PV with its content. - -## Migrating from coreos/prometheus-operator chart - -The multiple charts have been combined into a single chart that installs prometheus operator, prometheus, alertmanager, grafana as well as the multitude of exporters necessary to monitor a cluster. - -There is no simple and direct migration path between the charts as the changes are extensive and intended to make the chart easier to support. - -The capabilities of the old chart are all available in the new chart, including the ability to run multiple prometheus instances on a single cluster - you will need to disable the parts of the chart you do not wish to deploy. - -You can check out the tickets for this change [here](https://github.com/prometheus-operator/prometheus-operator/issues/592) and [here](https://github.com/helm/charts/pull/6765). - -### High-level overview of Changes - -#### Added dependencies - -The chart has added 3 [dependencies](#dependencies). - -- Node-Exporter, Kube-State-Metrics: These components are loaded as dependencies into the chart, and are relatively simple components -- Grafana: The Grafana chart is more feature-rich than this chart - it contains a sidecar that is able to load data sources and dashboards from configmaps deployed into the same cluster. For more information check out the [documentation for the chart](https://github.com/grafana/helm-charts/blob/main/charts/grafana/README.md) - -#### Kubelet Service - -Because the kubelet service has a new name in the chart, make sure to clean up the old kubelet service in the `kube-system` namespace to prevent counting container metrics twice. - -#### Persistent Volumes - -If you would like to keep the data of the current persistent volumes, it should be possible to attach existing volumes to new PVCs and PVs that are created using the conventions in the new chart. For example, in order to use an existing Azure disk for a helm release called `prometheus-migration` the following resources can be created: - -```yaml -apiVersion: v1 -kind: PersistentVolume -metadata: - name: pvc-prometheus-migration-prometheus-0 -spec: - accessModes: - - ReadWriteOnce - azureDisk: - cachingMode: None - diskName: pvc-prometheus-migration-prometheus-0 - diskURI: /subscriptions/f5125d82-2622-4c50-8d25-3f7ba3e9ac4b/resourceGroups/sample-migration-resource-group/providers/Microsoft.Compute/disks/pvc-prometheus-migration-prometheus-0 - fsType: "" - kind: Managed - readOnly: false - capacity: - storage: 1Gi - persistentVolumeReclaimPolicy: Delete - storageClassName: prometheus - volumeMode: Filesystem -``` - -```yaml -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - labels: - app.kubernetes.io/name: prometheus - prometheus: prometheus-migration-prometheus - name: prometheus-prometheus-migration-prometheus-db-prometheus-prometheus-migration-prometheus-0 - namespace: monitoring -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - storageClassName: prometheus - volumeMode: Filesystem - volumeName: pvc-prometheus-migration-prometheus-0 -``` - -The PVC will take ownership of the PV and when you create a release using a persistent volume claim template it will use the existing PVCs as they match the naming convention used by the chart. For other cloud providers similar approaches can be used. - -#### KubeProxy - -The metrics bind address of kube-proxy is default to `127.0.0.1:10249` that prometheus instances **cannot** access to. You should expose metrics by changing `metricsBindAddress` field value to `0.0.0.0:10249` if you want to collect them. - -Depending on the cluster, the relevant part `config.conf` will be in ConfigMap `kube-system/kube-proxy` or `kube-system/kube-proxy-config`. For example: - -```console -kubectl -n kube-system edit cm kube-proxy -``` - -```yaml -apiVersion: v1 -data: - config.conf: |- - apiVersion: kubeproxy.config.k8s.io/v1alpha1 - kind: KubeProxyConfiguration - # ... - # metricsBindAddress: 127.0.0.1:10249 - metricsBindAddress: 0.0.0.0:10249 - # ... - kubeconfig.conf: |- - # ... -kind: ConfigMap -metadata: - labels: - app: kube-proxy - name: kube-proxy - namespace: kube-system -``` diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/app-README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/app-README.md deleted file mode 100644 index 3920854384..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/app-README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Rancher Monitoring and Alerting - - This chart is based on the upstream [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) chart. The chart deploys [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator) and its CRDs along with [Grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana), [Prometheus Adapter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-adapter) and additional charts / Kubernetes manifests to gather metrics. It allows users to monitor their Kubernetes clusters, view metrics in Grafana dashboards, and set up alerts and notifications. - -For more information on how to use the feature, refer to our [docs](https://rancher.com/docs/rancher/v2.x/en/monitoring-alerting/v2.5/). - -The chart installs the following components: - -- [Prometheus Operator](https://github.com/coreos/prometheus-operator) - The operator provides easy monitoring definitions for Kubernetes services, manages [Prometheus](https://prometheus.io/) and [AlertManager](https://prometheus.io/docs/alerting/latest/alertmanager/) instances, and adds default scrape targets for some Kubernetes components. -- [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus/) - A collection of community-curated Kubernetes manifests, Grafana Dashboards, and PrometheusRules that deploy a default end-to-end cluster monitoring configuration. -- [Grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana) - Grafana allows a user to create / view dashboards based on the cluster metrics collected by Prometheus. -- [node-exporter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-node-exporter) / [kube-state-metrics](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics) / [rancher-pushprox](https://github.com/rancher/charts/tree/dev-v2.7/packages/rancher-monitoring/rancher-pushprox/charts) - These charts monitor various Kubernetes components across different Kubernetes cluster types. -- [Prometheus Adapter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-adapter) - The adapter allows a user to expose custom metrics, resource metrics, and external metrics on the default [Prometheus](https://prometheus.io/) instance to the Kubernetes API Server. - -For more information, review the Helm README of this chart. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. -​ -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Upgrading from 100.0.0+up16.6.0 to 100.1.0+up19.0.3 - -### Noticeable changes: -Grafana: -- `sidecar.dashboards.searchNamespace`, `sidecar.datasources.searchNamespace` and `sidecar.notifiers.searchNamespace` support a list of namespaces now. - -Kube-state-metrics -- the type of `collectors` is changed from Dictionary to List. -- `kubeStateMetrics.serviceMonitor.namespaceOverride` was replaced by `kube-state-metrics.namespaceOverride`. - -### Known issues: -- Occasionally, the upgrade fails with errors related to the webhook `prometheusrulemutate.monitoring.coreos.com`. This is a known issue in the upstream, and the workaround is to trigger the upgrade one more time. [32416](https://github.com/rancher/rancher/issues/32416#issuecomment-828881726) diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/.helmignore deleted file mode 100644 index 8cade1318f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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 -.vscode -.project -.idea/ -*.tmproj -OWNERS diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/Chart.yaml deleted file mode 100644 index 7770ebbe5a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/Chart.yaml +++ /dev/null @@ -1,41 +0,0 @@ -annotations: - artifacthub.io/license: Apache-2.0 - artifacthub.io/links: | - - name: Chart Source - url: https://github.com/grafana/helm-charts - - name: Upstream Project - url: https://github.com/grafana/grafana - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-grafana -apiVersion: v2 -appVersion: 11.1.0 -description: The leading tool for querying and visualizing time series and metrics. -home: https://grafana.com -icon: https://artifacthub.io/image/b4fed1a7-6c8f-4945-b99d-096efa3e4116 -keywords: -- monitoring -- metric -kubeVersion: '>=1.28.0-0' -maintainers: -- email: zanhsieh@gmail.com - name: zanhsieh -- email: rluckie@cisco.com - name: rtluckie -- email: maor.friedman@redhat.com - name: maorfr -- email: miroslav.hadzhiev@gmail.com - name: Xtigyro -- email: mail@torstenwalter.de - name: torstenwalter -- email: github@jkroepke.de - name: jkroepke -name: grafana -sources: -- https://github.com/grafana/grafana -- https://github.com/grafana/helm-charts -type: application -version: 8.3.6 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/README.md deleted file mode 100644 index f758963a4b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/README.md +++ /dev/null @@ -1,778 +0,0 @@ -# Grafana Helm Chart - -* Installs the web dashboarding system [Grafana](http://grafana.org/) - -## 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 -``` - -## 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. - -### To 4.0.0 (And 3.12.1) - -This version requires Helm >= 2.12.0. - -### To 5.0.0 - -You have to add --force to your helm upgrade command as the labels of the chart have changed. - -### To 6.0.0 - -This version requires Helm >= 3.1.0. - -### To 7.0.0 - -For consistency with other Helm charts, the `global.image.registry` parameter was renamed -to `global.imageRegistry`. If you were not previously setting `global.image.registry`, no action -is required on upgrade. If you were previously setting `global.image.registry`, you will -need to instead set `global.imageRegistry`. - -## Configuration - -| Parameter | Description | Default | -|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| -| `replicas` | Number of nodes | `1` | -| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | -| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `nil` | -| `podDisruptionBudget.apiVersion` | Pod disruption apiVersion | `nil` | -| `deploymentStrategy` | Deployment strategy | `{ "type": "RollingUpdate" }` | -| `livenessProbe` | Liveness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10 }` | -| `readinessProbe` | Readiness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } }`| -| `securityContext` | Deployment securityContext | `{"runAsUser": 472, "runAsGroup": 472, "fsGroup": 472}` | -| `priorityClassName` | Name of Priority Class to assign pods | `nil` | -| `image.registry` | Image registry | `docker.io` | -| `image.repository` | Image repository | `grafana/grafana` | -| `image.tag` | Overrides the Grafana image tag whose default is the chart appVersion (`Must be >= 5.0.0`) | `` | -| `image.sha` | Image sha (optional) | `` | -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `image.pullSecrets` | Image pull secrets (can be templated) | `[]` | -| `service.enabled` | Enable grafana service | `true` | -| `service.ipFamilies` | Kubernetes service IP families | `[]` | -| `service.ipFamilyPolicy` | Kubernetes service IP family policy | `""` | -| `service.type` | Kubernetes service type | `ClusterIP` | -| `service.port` | Kubernetes port where service is exposed | `80` | -| `service.portName` | Name of the port on the service | `service` | -| `service.appProtocol` | Adds the appProtocol field to the service | `` | -| `service.targetPort` | Internal service is port | `3000` | -| `service.nodePort` | Kubernetes service nodePort | `nil` | -| `service.annotations` | Service annotations (can be templated) | `{}` | -| `service.labels` | Custom labels | `{}` | -| `service.clusterIP` | internal cluster service IP | `nil` | -| `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `nil` | -| `service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to lb (if supported) | `[]` | -| `service.externalIPs` | service external IP addresses | `[]` | -| `service.externalTrafficPolicy` | change the default externalTrafficPolicy | `nil` | -| `headlessService` | Create a headless service | `false` | -| `extraExposePorts` | Additional service ports for sidecar containers| `[]` | -| `hostAliases` | adds rules to the pod's /etc/hosts | `[]` | -| `ingress.enabled` | Enables Ingress | `false` | -| `ingress.annotations` | Ingress annotations (values are templated) | `{}` | -| `ingress.labels` | Custom labels | `{}` | -| `ingress.path` | Ingress accepted path | `/` | -| `ingress.pathType` | Ingress type of path | `Prefix` | -| `ingress.hosts` | Ingress accepted hostnames | `["chart-example.local"]` | -| `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/guide/ingress/annotations/#actions). Requires `ingress.hosts` to have one or more host entries. | `[]` | -| `ingress.tls` | Ingress TLS configuration | `[]` | -| `ingress.ingressClassName` | Ingress Class Name. MAY be required for Kubernetes versions >= 1.18 | `""` | -| `resources` | CPU/Memory resource requests/limits | `{}` | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `tolerations` | Toleration labels for pod assignment | `[]` | -| `affinity` | Affinity settings for pod assignment | `{}` | -| `extraInitContainers` | Init containers to add to the grafana pod | `{}` | -| `extraContainers` | Sidecar containers to add to the grafana pod | `""` | -| `extraContainerVolumes` | Volumes that can be mounted in sidecar containers | `[]` | -| `extraLabels` | Custom labels for all manifests | `{}` | -| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | -| `persistence.enabled` | Use persistent volume to store data | `false` | -| `persistence.type` | Type of persistence (`pvc` or `statefulset`) | `pvc` | -| `persistence.size` | Size of persistent volume claim | `10Gi` | -| `persistence.existingClaim` | Use an existing PVC to persist data (can be templated) | `nil` | -| `persistence.storageClassName` | Type of persistent volume claim | `nil` | -| `persistence.accessModes` | Persistence access modes | `[ReadWriteOnce]` | -| `persistence.annotations` | PersistentVolumeClaim annotations | `{}` | -| `persistence.finalizers` | PersistentVolumeClaim finalizers | `[ "kubernetes.io/pvc-protection" ]` | -| `persistence.extraPvcLabels` | Extra labels to apply to a PVC. | `{}` | -| `persistence.subPath` | Mount a sub dir of the persistent volume (can be templated) | `nil` | -| `persistence.inMemory.enabled` | If persistence is not enabled, whether to mount the local storage in-memory to improve performance | `false` | -| `persistence.inMemory.sizeLimit` | SizeLimit for the in-memory local storage | `nil` | -| `persistence.disableWarning` | Hide NOTES warning, useful when persiting to a database | `false` | -| `initChownData.enabled` | If false, don't reset data ownership at startup | true | -| `initChownData.image.registry` | init-chown-data container image registry | `docker.io` | -| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | -| `initChownData.image.tag` | init-chown-data container image tag | `1.31.1` | -| `initChownData.image.sha` | init-chown-data container image sha (optional)| `""` | -| `initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` | -| `initChownData.resources` | init-chown-data pod resource requests & limits | `{}` | -| `schedulerName` | Alternate scheduler name | `nil` | -| `env` | Extra environment variables passed to pods | `{}` | -| `envValueFrom` | Environment variables from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | -| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | -| `envFromSecrets` | List of Kubernetes secrets (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | -| `envFromConfigMaps` | List of Kubernetes ConfigMaps (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | -| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret. (passed through [tpl](https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function)) | `{}` | -| `enableServiceLinks` | Inject Kubernetes services as environment variables. | `true` | -| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | -| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | -| `extraVolumes` | Additional Grafana server volumes | `[]` | -| `automountServiceAccountToken` | Mounted the service account token on the grafana pod. Mandatory, if sidecars are enabled | `true` | -| `createConfigmap` | Enable creating the grafana configmap | `true` | -| `extraConfigmapMounts` | Additional grafana server configMap volume mounts (values are templated) | `[]` | -| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | -| `plugins` | Plugins to be loaded along with Grafana | `[]` | -| `datasources` | Configure grafana datasources (passed through tpl) | `{}` | -| `alerting` | Configure grafana alerting (passed through tpl) | `{}` | -| `notifiers` | Configure grafana notifiers | `{}` | -| `dashboardProviders` | Configure grafana dashboard providers | `{}` | -| `dashboards` | Dashboards to import | `{}` | -| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` | -| `grafana.ini` | Grafana's primary configuration | `{}` | -| `global.imageRegistry` | Global image pull registry for all images. | `null` | -| `global.imagePullSecrets` | Global image pull secrets (can be templated). Allows either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). | `[]` | -| `ldap.enabled` | Enable LDAP authentication | `false` | -| `ldap.existingSecret` | The name of an existing secret containing the `ldap.toml` file, this must have the key `ldap-toml`. | `""` | -| `ldap.config` | Grafana's LDAP configuration | `""` | -| `annotations` | Deployment annotations | `{}` | -| `labels` | Deployment labels | `{}` | -| `podAnnotations` | Pod annotations | `{}` | -| `podLabels` | Pod labels | `{}` | -| `podPortName` | Name of the grafana port on the pod | `grafana` | -| `lifecycleHooks` | Lifecycle hooks for podStart and preStop [Example](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/#define-poststart-and-prestop-handlers) | `{}` | -| `sidecar.image.registry` | Sidecar image registry | `quay.io` | -| `sidecar.image.repository` | Sidecar image repository | `kiwigrid/k8s-sidecar` | -| `sidecar.image.tag` | Sidecar image tag | `1.26.0` | -| `sidecar.image.sha` | Sidecar image sha (optional) | `""` | -| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | -| `sidecar.resources` | Sidecar resources | `{}` | -| `sidecar.securityContext` | Sidecar securityContext | `{}` | -| `sidecar.enableUniqueFilenames` | Sets the kiwigrid/k8s-sidecar UNIQUE_FILENAMES environment variable. If set to `true` the sidecar will create unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | `false` | -| `sidecar.alerts.enabled` | Enables the cluster wide search for alerts and adds/updates/deletes them in grafana |`false` | -| `sidecar.alerts.label` | Label that config maps with alerts should have to be added | `grafana_alert` | -| `sidecar.alerts.labelValue` | Label value that config maps with alerts should have to be added | `""` | -| `sidecar.alerts.searchNamespace` | Namespaces list. If specified, the sidecar will search for alerts config-maps 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. | `nil` | -| `sidecar.alerts.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | -| `sidecar.alerts.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | -| `sidecar.alerts.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/alerting/reload"` | -| `sidecar.alerts.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | -| `sidecar.alerts.initAlerts` | Set to true to deploy the alerts sidecar as an initContainer. This is needed if skipReload is true, to load any alerts defined at startup time. | `false` | -| `sidecar.alerts.extraMounts` | Additional alerts sidecar volume mounts. | `[]` | -| `sidecar.dashboards.enabled` | Enables the cluster wide search for dashboards and adds/updates/deletes them in grafana | `false` | -| `sidecar.dashboards.SCProvider` | Enables creation of sidecar provider | `true` | -| `sidecar.dashboards.provider.name` | Unique name of the grafana provider | `sidecarProvider` | -| `sidecar.dashboards.provider.orgid` | Id of the organisation, to which the dashboards should be added | `1` | -| `sidecar.dashboards.provider.folder` | Logical folder in which grafana groups dashboards | `""` | -| `sidecar.dashboards.provider.folderUid` | Allows you to specify the static UID for the logical folder above | `""` | -| `sidecar.dashboards.provider.disableDelete` | Activate to avoid the deletion of imported dashboards | `false` | -| `sidecar.dashboards.provider.allowUiUpdates` | Allow updating provisioned dashboards from the UI | `false` | -| `sidecar.dashboards.provider.type` | Provider type | `file` | -| `sidecar.dashboards.provider.foldersFromFilesStructure` | Allow Grafana to replicate dashboard structure from filesystem. | `false` | -| `sidecar.dashboards.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | -| `sidecar.skipTlsVerify` | Set to true to skip tls verification for kube api calls | `nil` | -| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | `grafana_dashboard` | -| `sidecar.dashboards.labelValue` | Label value that config maps with dashboards should have to be added | `""` | -| `sidecar.dashboards.folder` | Folder in the pod that should hold the collected dashboards (unless `sidecar.dashboards.defaultFolderName` is set). This path will be mounted. | `/tmp/dashboards` | -| `sidecar.dashboards.folderAnnotation` | The annotation the sidecar will look for in configmaps to override the destination folder for files | `nil` | -| `sidecar.dashboards.defaultFolderName` | The default folder name, it will create a subfolder under the `sidecar.dashboards.folder` and put dashboards in there instead | `nil` | -| `sidecar.dashboards.searchNamespace` | Namespaces list. If specified, the sidecar will search for dashboards config-maps 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. | `nil` | -| `sidecar.dashboards.script` | Absolute path to shell script to execute after a configmap got reloaded. | `nil` | -| `sidecar.dashboards.reloadURL` | Full url of dashboards configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/dashboards/reload"` | -| `sidecar.dashboards.skipReload` | Enabling this omits defining the REQ_USERNAME, REQ_PASSWORD, REQ_URL and REQ_METHOD environment variables | `false` | -| `sidecar.dashboards.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | -| `sidecar.dashboards.extraMounts` | Additional dashboard sidecar volume mounts. | `[]` | -| `sidecar.datasources.enabled` | Enables the cluster wide search for datasources and adds/updates/deletes them in grafana |`false` | -| `sidecar.datasources.label` | Label that config maps with datasources should have to be added | `grafana_datasource` | -| `sidecar.datasources.labelValue` | Label value that config maps with datasources should have to be added | `""` | -| `sidecar.datasources.searchNamespace` | Namespaces list. If specified, the sidecar will search for datasources config-maps 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. | `nil` | -| `sidecar.datasources.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | -| `sidecar.datasources.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | -| `sidecar.datasources.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | -| `sidecar.datasources.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | -| `sidecar.datasources.initDatasources` | Set to true to deploy the datasource sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any datasources defined at startup time. | `false` | -| `sidecar.notifiers.enabled` | Enables the cluster wide search for notifiers and adds/updates/deletes them in grafana | `false` | -| `sidecar.notifiers.label` | Label that config maps with notifiers should have to be added | `grafana_notifier` | -| `sidecar.notifiers.labelValue` | Label value that config maps with notifiers should have to be added | `""` | -| `sidecar.notifiers.searchNamespace` | Namespaces list. If specified, the sidecar will search for notifiers config-maps (or 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. | `nil` | -| `sidecar.notifiers.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | -| `sidecar.notifiers.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | -| `sidecar.notifiers.reloadURL` | Full url of notifier configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/notifications/reload"` | -| `sidecar.notifiers.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | -| `sidecar.notifiers.initNotifiers` | Set to true to deploy the notifier sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any notifiers defined at startup time. | `false` | -| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials. | `""` | -| `smtp.userKey` | The key in the existing SMTP secret containing the username. | `"user"` | -| `smtp.passwordKey` | The key in the existing SMTP secret containing the password. | `"password"` | -| `admin.existingSecret` | The name of an existing secret containing the admin credentials (can be templated). | `""` | -| `admin.userKey` | The key in the existing admin secret containing the username. | `"admin-user"` | -| `admin.passwordKey` | The key in the existing admin secret containing the password. | `"admin-password"` | -| `serviceAccount.automountServiceAccountToken` | Automount the service account token on all pods where is service account is used | `false` | -| `serviceAccount.annotations` | ServiceAccount annotations | | -| `serviceAccount.create` | Create service account | `true` | -| `serviceAccount.labels` | ServiceAccount labels | `{}` | -| `serviceAccount.name` | Service account name to use, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `` | -| `serviceAccount.nameTest` | Service account name to use for test, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `nil` | -| `rbac.create` | Create and use RBAC resources | `true` | -| `rbac.namespaced` | Creates Role and Rolebinding instead of the default ClusterRole and ClusteRoleBindings for the grafana instance | `false` | -| `rbac.useExistingRole` | Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. | `nil` | -| `rbac.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `false` | -| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `false` | -| `rbac.extraRoleRules` | Additional rules to add to the Role | [] | -| `rbac.extraClusterRoleRules` | Additional rules to add to the ClusterRole | [] | -| `command` | Define command to be executed by grafana container at startup | `nil` | -| `args` | Define additional args if command is used | `nil` | -| `testFramework.enabled` | Whether to create test-related resources | `true` | -| `testFramework.image.registry` | `test-framework` image registry. | `docker.io` | -| `testFramework.image.repository` | `test-framework` image repository. | `bats/bats` | -| `testFramework.image.tag` | `test-framework` image tag. | `v1.4.1` | -| `testFramework.imagePullPolicy` | `test-framework` image pull policy. | `IfNotPresent` | -| `testFramework.securityContext` | `test-framework` securityContext | `{}` | -| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | -| `downloadDashboards.envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | -| `downloadDashboards.resources` | Resources of `download-dashboards` container | `{}` | -| `downloadDashboardsImage.registry` | Curl docker image registry | `docker.io` | -| `downloadDashboardsImage.repository` | Curl docker image repository | `curlimages/curl` | -| `downloadDashboardsImage.tag` | Curl docker image tag | `7.73.0` | -| `downloadDashboardsImage.sha` | Curl docker image sha (optional) | `""` | -| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | -| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | -| `serviceMonitor.enabled` | Use servicemonitor from prometheus operator | `false` | -| `serviceMonitor.namespace` | Namespace this servicemonitor is installed in | | -| `serviceMonitor.interval` | How frequently Prometheus should scrape | `1m` | -| `serviceMonitor.path` | Path to scrape | `/metrics` | -| `serviceMonitor.scheme` | Scheme to use for metrics scraping | `http` | -| `serviceMonitor.tlsConfig` | TLS configuration block for the endpoint | `{}` | -| `serviceMonitor.labels` | Labels for the servicemonitor passed to Prometheus Operator | `{}` | -| `serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `30s` | -| `serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping. | `[]` | -| `serviceMonitor.metricRelabelings` | MetricRelabelConfigs to apply to samples before ingestion. | `[]` | -| `revisionHistoryLimit` | Number of old ReplicaSets to retain | `10` | -| `imageRenderer.enabled` | Enable the image-renderer deployment & service | `false` | -| `imageRenderer.image.registry` | image-renderer Image registry | `docker.io` | -| `imageRenderer.image.repository` | image-renderer Image repository | `grafana/grafana-image-renderer` | -| `imageRenderer.image.tag` | image-renderer Image tag | `latest` | -| `imageRenderer.image.sha` | image-renderer Image sha (optional) | `""` | -| `imageRenderer.image.pullPolicy` | image-renderer ImagePullPolicy | `Always` | -| `imageRenderer.env` | extra env-vars for image-renderer | `{}` | -| `imageRenderer.envValueFrom` | Environment variables for image-renderer from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | -| `imageRenderer.extraConfigmapMounts` | Additional image-renderer configMap volume mounts (values are templated) | `[]` | -| `imageRenderer.extraSecretMounts` | Additional image-renderer secret volume mounts | `[]` | -| `imageRenderer.extraVolumeMounts` | Additional image-renderer volume mounts | `[]` | -| `imageRenderer.extraVolumes` | Additional image-renderer volumes | `[]` | -| `imageRenderer.serviceAccountName` | image-renderer deployment serviceAccountName | `""` | -| `imageRenderer.securityContext` | image-renderer deployment securityContext | `{}` | -| `imageRenderer.podAnnotations` | image-renderer image-renderer pod annotation | `{}` | -| `imageRenderer.hostAliases` | image-renderer deployment Host Aliases | `[]` | -| `imageRenderer.priorityClassName` | image-renderer deployment priority class | `''` | -| `imageRenderer.service.enabled` | Enable the image-renderer service | `true` | -| `imageRenderer.service.portName` | image-renderer service port name | `http` | -| `imageRenderer.service.port` | image-renderer port used by deployment | `8081` | -| `imageRenderer.service.targetPort` | image-renderer service port used by service | `8081` | -| `imageRenderer.appProtocol` | Adds the appProtocol field to the service | `` | -| `imageRenderer.grafanaSubPath` | Grafana sub path to use for image renderer callback url | `''` | -| `imageRenderer.podPortName` | name of the image-renderer port on the pod | `http` | -| `imageRenderer.revisionHistoryLimit` | number of image-renderer replica sets to keep | `10` | -| `imageRenderer.networkPolicy.limitIngress` | Enable a NetworkPolicy to limit inbound traffic from only the created grafana pods | `true` | -| `imageRenderer.networkPolicy.limitEgress` | Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods | `false` | -| `imageRenderer.resources` | Set resource limits for image-renderer pods | `{}` | -| `imageRenderer.nodeSelector` | Node labels for pod assignment | `{}` | -| `imageRenderer.tolerations` | Toleration labels for pod assignment | `[]` | -| `imageRenderer.affinity` | Affinity settings for pod assignment | `{}` | -| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` | -| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | -| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed | `{}` | -| `networkPolicy.ingress` | Enable the creation of an ingress network policy | `true` | -| `networkPolicy.egress.enabled` | Enable the creation of an egress network policy | `false` | -| `networkPolicy.egress.ports` | An array of ports to allow for the egress | `[]` | -| `enableKubeBackwardCompatibility` | Enable backward compatibility of kubernetes where pod's defintion version below 1.13 doesn't have the enableServiceLinks option | `false` | - -### Example ingress with path - -With grafana 6.3 and above - -```yaml -grafana.ini: - server: - domain: monitoring.example.com - root_url: "%(protocol)s://%(domain)s/grafana" - serve_from_sub_path: true -ingress: - enabled: true - hosts: - - "monitoring.example.com" - path: "/grafana" -``` - -### Example of extraVolumeMounts and extraVolumes - -Configure additional volumes with `extraVolumes` and volume mounts with `extraVolumeMounts`. - -Example for `extraVolumeMounts` and corresponding `extraVolumes`: - -```yaml -extraVolumeMounts: - - name: plugins - mountPath: /var/lib/grafana/plugins - subPath: configs/grafana/plugins - readOnly: false - - name: dashboards - mountPath: /var/lib/grafana/dashboards - hostPath: /usr/shared/grafana/dashboards - readOnly: false - -extraVolumes: - - name: plugins - existingClaim: existing-grafana-claim - - name: dashboards - hostPath: /usr/shared/grafana/dashboards -``` - -Volumes default to `emptyDir`. Set to `persistentVolumeClaim`, -`hostPath`, `csi`, or `configMap` for other types. For a -`persistentVolumeClaim`, specify an existing claim name with -`existingClaim`. - -## Import dashboards - -There are a few methods to import dashboards to Grafana. Below are some examples and explanations as to how to use each method: - -```yaml -dashboards: - default: - some-dashboard: - json: | - { - "annotations": - - ... - # Complete json file here - ... - - "title": "Some Dashboard", - "uid": "abcd1234", - "version": 1 - } - custom-dashboard: - # This is a path to a file inside the dashboards directory inside the chart directory - file: dashboards/custom-dashboard.json - prometheus-stats: - # Ref: https://grafana.com/dashboards/2 - gnetId: 2 - revision: 2 - datasource: Prometheus - loki-dashboard-quick-search: - gnetId: 12019 - revision: 2 - datasource: - - name: DS_PROMETHEUS - value: Prometheus - - name: DS_LOKI - value: Loki - local-dashboard: - url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json -``` - -## BASE64 dashboards - -Dashboards could be stored on a server that does not return JSON directly and instead of it returns a Base64 encoded file (e.g. Gerrit) -A new parameter has been added to the url use case so if you specify a b64content value equals to true after the url entry a Base64 decoding is applied before save the file to disk. -If this entry is not set or is equals to false not decoding is applied to the file before saving it to disk. - -### Gerrit use case - -Gerrit API for download files has the following schema: where {project-name} and -{file-id} usually has '/' in their values and so they MUST be replaced by %2F so if project-name is user/repo, branch-id is master and file-id is equals to dir1/dir2/dashboard -the url value is - -## Sidecar for dashboards - -If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana -pod. This container watches all configmaps (or secrets) in the cluster and filters out the ones with -a label as defined in `sidecar.dashboards.label`. The files defined in those configmaps are written -to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported -dashboards are deleted/updated. - -A recommendation is to use one configmap per dashboard, as a reduction of multiple dashboards inside -one configmap is currently not properly mirrored in grafana. - -Example dashboard config: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: sample-grafana-dashboard - labels: - grafana_dashboard: "1" -data: - k8s-dashboard.json: |- - [...] -``` - -## Sidecar for datasources - -If the parameter `sidecar.datasources.enabled` is set, an init container is deployed in the grafana -pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and -filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in -those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, -the data sources in grafana can be imported. - -Should you aim for reloading datasources in Grafana each time the config is changed, set `sidecar.datasources.skipReload: false` and adjust `sidecar.datasources.reloadURL` to `http://..svc.cluster.local/api/admin/provisioning/datasources/reload`. - -Secrets are recommended over configmaps for this usecase because datasources usually contain private -data like usernames and passwords. Secrets are the more appropriate cluster resource to manage those. - -Example values to add a postgres datasource as a kubernetes secret: -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: grafana-datasources - labels: - grafana_datasource: 'true' # default value for: sidecar.datasources.label -stringData: - pg-db.yaml: |- - apiVersion: 1 - datasources: - - name: My pg db datasource - type: postgres - url: my-postgresql-db:5432 - user: db-readonly-user - secureJsonData: - password: 'SUperSEcretPa$$word' - jsonData: - database: my_datase - sslmode: 'disable' # disable/require/verify-ca/verify-full - maxOpenConns: 0 # Grafana v5.4+ - maxIdleConns: 2 # Grafana v5.4+ - connMaxLifetime: 14400 # Grafana v5.4+ - postgresVersion: 1000 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10 - timescaledb: false - # allow users to edit datasources from the UI. - editable: false -``` - -Example values to add a datasource adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): - -```yaml -datasources: - datasources.yaml: - apiVersion: 1 - datasources: - # name of the datasource. Required - - name: Graphite - # datasource type. Required - type: graphite - # access mode. proxy or direct (Server or Browser in the UI). Required - access: proxy - # org id. will default to orgId 1 if not specified - orgId: 1 - # url - url: http://localhost:8080 - # database password, if used - password: - # database user, if used - user: - # database name, if used - database: - # enable/disable basic auth - basicAuth: - # basic auth username - basicAuthUser: - # basic auth password - basicAuthPassword: - # enable/disable with credentials headers - withCredentials: - # mark as default datasource. Max one per org - isDefault: - # fields that will be converted to json and stored in json_data - jsonData: - graphiteVersion: "1.1" - tlsAuth: true - tlsAuthWithCACert: true - # json object of data that will be encrypted. - secureJsonData: - tlsCACert: "..." - tlsClientCert: "..." - tlsClientKey: "..." - version: 1 - # allow users to edit datasources from the UI. - editable: false -``` - -## Sidecar for notifiers - -If the parameter `sidecar.notifiers.enabled` is set, an init container is deployed in the grafana -pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and -filters out the ones with a label as defined in `sidecar.notifiers.label`. The files defined in -those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, -the notification channels in grafana can be imported. The secrets must be created before -`helm install` so that the notifiers init container can list the secrets. - -Secrets are recommended over configmaps for this usecase because alert notification channels usually contain -private data like SMTP usernames and passwords. Secrets are the more appropriate cluster resource to manage those. - -Example datasource config adapted from [Grafana](https://grafana.com/docs/grafana/latest/administration/provisioning/#alert-notification-channels): - -```yaml -notifiers: - - name: notification-channel-1 - type: slack - uid: notifier1 - # either - org_id: 2 - # or - org_name: Main Org. - is_default: true - send_reminder: true - frequency: 1h - disable_resolve_message: false - # See `Supported Settings` section for settings supporter for each - # alert notification type. - settings: - recipient: 'XXX' - token: 'xoxb' - uploadImage: true - url: https://slack.com - -delete_notifiers: - - name: notification-channel-1 - uid: notifier1 - org_id: 2 - - name: notification-channel-2 - # default org_id: 1 -``` - -## Sidecar for alerting resources - -If the parameter `sidecar.alerts.enabled` is set, a sidecar container is deployed in the grafana -pod. This container watches all configmaps (or secrets) in the cluster (namespace defined by `sidecar.alerts.searchNamespace`) and filters out the ones with -a label as defined in `sidecar.alerts.label` (default is `grafana_alert`). The files defined in those configmaps are written -to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported alerting resources are updated, however, deletions are a little more complicated (see below). - -This sidecar can be used to provision alert rules, contact points, notification policies, notification templates and mute timings as shown in [Grafana Documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/). - -To fetch the alert config which will be provisioned, use the alert provisioning API ([Grafana Documentation](https://grafana.com/docs/grafana/next/developers/http_api/alerting_provisioning/)). -You can use either JSON or YAML format. - -Example config for an alert rule: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: sample-grafana-alert - labels: - grafana_alert: "1" -data: - k8s-alert.yml: |- - apiVersion: 1 - groups: - - orgId: 1 - name: k8s-alert - [...] -``` - -To delete provisioned alert rules is a two step process, you need to delete the configmap which defined the alert rule -and then create a configuration which deletes the alert rule. - -Example deletion configuration: -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: delete-sample-grafana-alert - namespace: monitoring - labels: - grafana_alert: "1" -data: - delete-k8s-alert.yml: |- - apiVersion: 1 - deleteRules: - - orgId: 1 - uid: 16624780-6564-45dc-825c-8bded4ad92d3 -``` - -## Statically provision alerting resources -If you don't need to change alerting resources (alert rules, contact points, notification policies and notification templates) regularly you could use the `alerting` config option instead of the sidecar option above. -This will grab the alerting config and apply it statically at build time for the helm file. - -There are two methods to statically provision alerting configuration in Grafana. Below are some examples and explanations as to how to use each method: - -```yaml -alerting: - team1-alert-rules.yaml: - file: alerting/team1/rules.yaml - team2-alert-rules.yaml: - file: alerting/team2/rules.yaml - team3-alert-rules.yaml: - file: alerting/team3/rules.yaml - notification-policies.yaml: - file: alerting/shared/notification-policies.yaml - notification-templates.yaml: - file: alerting/shared/notification-templates.yaml - contactpoints.yaml: - apiVersion: 1 - contactPoints: - - orgId: 1 - name: Slack channel - receivers: - - uid: default-receiver - type: slack - settings: - # Webhook URL to be filled in - url: "" - # We need to escape double curly braces for the tpl function. - text: '{{ `{{ template "default.message" . }}` }}' - title: '{{ `{{ template "default.title" . }}` }}' -``` - -The two possibilities for static alerting resource provisioning are: - -* Inlining the file contents as shown for contact points in the above example. -* Importing a file using a relative path starting from the chart root directory as shown for the alert rules in the above example. - -### Important notes on file provisioning - -* The format of the files is defined in the [Grafana documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/) on file provisioning. -* The chart supports importing YAML and JSON files. -* The filename must be unique, otherwise one volume mount will overwrite the other. -* In case of inlining, double curly braces that arise from the Grafana configuration format and are not intended as templates for the chart must be escaped. -* The number of total files under `alerting:` is not limited. Each file will end up as a volume mount in the corresponding provisioning folder of the deployed Grafana instance. -* The file size for each import is limited by what the function `.Files.Get` can handle, which suffices for most cases. - -## How to serve Grafana with a path prefix (/grafana) - -In order to serve Grafana with a prefix (e.g., ), add the following to your values.yaml. - -```yaml -ingress: - enabled: true - annotations: - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/rewrite-target: /$1 - nginx.ingress.kubernetes.io/use-regex: "true" - - path: /grafana/?(.*) - hosts: - - k8s.example.dev - -grafana.ini: - server: - root_url: http://localhost:3000/grafana # this host can be localhost -``` - -## How to securely reference secrets in grafana.ini - -This example uses Grafana [file providers](https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider) for secret values and the `extraSecretMounts` configuration flag (Additional grafana server secret mounts) to mount the secrets. - -In grafana.ini: - -```yaml -grafana.ini: - [auth.generic_oauth] - enabled = true - client_id = $__file{/etc/secrets/auth_generic_oauth/client_id} - client_secret = $__file{/etc/secrets/auth_generic_oauth/client_secret} -``` - -Existing secret, or created along with helm: - -```yaml ---- -apiVersion: v1 -kind: Secret -metadata: - name: auth-generic-oauth-secret -type: Opaque -stringData: - client_id: - client_secret: -``` - -Include in the `extraSecretMounts` configuration flag: - -```yaml -- extraSecretMounts: - - name: auth-generic-oauth-secret-mount - secretName: auth-generic-oauth-secret - defaultMode: 0440 - mountPath: /etc/secrets/auth_generic_oauth - readOnly: true -``` - -### extraSecretMounts using a Container Storage Interface (CSI) provider - -This example uses a CSI driver e.g. retrieving secrets using [Azure Key Vault Provider](https://github.com/Azure/secrets-store-csi-driver-provider-azure) - -```yaml -- extraSecretMounts: - - name: secrets-store-inline - mountPath: /run/secrets - readOnly: true - csi: - driver: secrets-store.csi.k8s.io - readOnly: true - volumeAttributes: - secretProviderClass: "my-provider" - nodePublishSecretRef: - name: akv-creds -``` - -## Image Renderer Plug-In - -This chart supports enabling [remote image rendering](https://github.com/grafana/grafana-image-renderer/blob/master/README.md#run-in-docker) - -```yaml -imageRenderer: - enabled: true -``` - -### Image Renderer NetworkPolicy - -By default the image-renderer pods will have a network policy which only allows ingress traffic from the created grafana instance - -### High Availability for unified alerting - -If you want to run Grafana in a high availability cluster you need to enable -the headless service by setting `headlessService: true` in your `values.yaml` -file. - -As next step you have to setup the `grafana.ini` in your `values.yaml` in a way -that it will make use of the headless service to obtain all the IPs of the -cluster. You should replace ``{{ Name }}`` with the name of your helm deployment. - -```yaml -grafana.ini: - ... - unified_alerting: - enabled: true - ha_peers: {{ Name }}-headless:9094 - ha_listen_address: ${POD_IP}:9094 - ha_advertise_address: ${POD_IP}:9094 - - alerting: - enabled: false -``` diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/dashboards/custom-dashboard.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/dashboards/custom-dashboard.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/dashboards/custom-dashboard.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/NOTES.txt deleted file mode 100644 index a40f666a47..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/NOTES.txt +++ /dev/null @@ -1,55 +0,0 @@ -1. Get your '{{ .Values.adminUser }}' user password by running: - - kubectl get secret --namespace {{ include "grafana.namespace" . }} {{ .Values.admin.existingSecret | default (include "grafana.fullname" .) }} -o jsonpath="{.data.{{ .Values.admin.passwordKey | default "admin-password" }}}" | base64 --decode ; echo - - -2. The Grafana server can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster: - - {{ include "grafana.fullname" . }}.{{ include "grafana.namespace" . }}.svc.cluster.local -{{ if .Values.ingress.enabled }} - If you bind grafana to 80, please update values in values.yaml and reinstall: - ``` - securityContext: - runAsUser: 0 - runAsGroup: 0 - fsGroup: 0 - - command: - - "setcap" - - "'cap_net_bind_service=+ep'" - - "/usr/sbin/grafana-server &&" - - "sh" - - "/run.sh" - ``` - Details refer to https://grafana.com/docs/installation/configuration/#http-port. - Or grafana would always crash. - - From outside the cluster, the server URL(s) are: - {{- range .Values.ingress.hosts }} - http://{{ . }} - {{- end }} -{{- else }} - Get the Grafana URL to visit by running these commands in the same shell: - {{- if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ include "grafana.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "grafana.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ include "grafana.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo 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. - You can watch the status of by running 'kubectl get svc --namespace {{ include "grafana.namespace" . }} -w {{ include "grafana.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ include "grafana.namespace" . }} {{ include "grafana.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - http://$SERVICE_IP:{{ .Values.service.port -}} - {{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ include "grafana.namespace" . }} -l "app.kubernetes.io/name={{ include "grafana.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace {{ include "grafana.namespace" . }} port-forward $POD_NAME 3000 - {{- end }} -{{- end }} - -3. Login with the password from step 1 and the username: {{ .Values.adminUser }} - -{{- if and (not .Values.persistence.enabled) (not .Values.persistence.disableWarning) }} -################################################################################# -###### WARNING: Persistence is disabled!!! You will lose your data when ##### -###### the Grafana pod is terminated. ##### -################################################################################# -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_config.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_config.tpl deleted file mode 100644 index b866217f2e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_config.tpl +++ /dev/null @@ -1,172 +0,0 @@ -{{/* - Generate config map data - */}} -{{- define "grafana.configData" -}} -{{ include "grafana.assertNoLeakedSecrets" . }} -{{- $files := .Files }} -{{- $root := . -}} -{{- with .Values.plugins }} -plugins: {{ join "," . }} -{{- end }} -grafana.ini: | -{{- range $elem, $elemVal := index .Values "grafana.ini" }} - {{- if not (kindIs "map" $elemVal) }} - {{- if kindIs "invalid" $elemVal }} - {{ $elem }} = - {{- else if kindIs "string" $elemVal }} - {{ $elem }} = {{ tpl $elemVal $ }} - {{- else }} - {{ $elem }} = {{ $elemVal }} - {{- end }} - {{- end }} -{{- end }} -{{- range $key, $value := index .Values "grafana.ini" }} - {{- if kindIs "map" $value }} - [{{ $key }}] - {{- range $elem, $elemVal := $value }} - {{- if kindIs "invalid" $elemVal }} - {{ $elem }} = - {{- else if kindIs "string" $elemVal }} - {{ $elem }} = {{ tpl $elemVal $ }} - {{- else }} - {{ $elem }} = {{ $elemVal }} - {{- end }} - {{- end }} - {{- end }} -{{- end }} - -{{- range $key, $value := .Values.datasources }} -{{- if not (hasKey $value "secret") }} -{{ $key }}: | - {{- tpl (toYaml $value | nindent 2) $root }} -{{- end }} -{{- end }} - -{{- range $key, $value := .Values.notifiers }} -{{- if not (hasKey $value "secret") }} -{{ $key }}: | - {{- toYaml $value | nindent 2 }} -{{- end }} -{{- end }} - -{{- range $key, $value := .Values.alerting }} -{{- if (hasKey $value "file") }} -{{ $key }}: -{{- toYaml ( $files.Get $value.file ) | nindent 2 }} -{{- else if (or (hasKey $value "secret") (hasKey $value "secretFile"))}} -{{/* will be stored inside secret generated by "configSecret.yaml"*/}} -{{- else }} -{{ $key }}: | - {{- tpl (toYaml $value | nindent 2) $root }} -{{- end }} -{{- end }} - -{{- range $key, $value := .Values.dashboardProviders }} -{{ $key }}: | - {{- toYaml $value | nindent 2 }} -{{- end }} - -{{- if .Values.dashboards }} -download_dashboards.sh: | - #!/usr/bin/env sh - set -euf - {{- if .Values.dashboardProviders }} - {{- range $key, $value := .Values.dashboardProviders }} - {{- range $value.providers }} - mkdir -p {{ .options.path }} - {{- end }} - {{- end }} - {{- end }} -{{ $dashboardProviders := .Values.dashboardProviders }} -{{- range $provider, $dashboards := .Values.dashboards }} - {{- range $key, $value := $dashboards }} - {{- if (or (hasKey $value "gnetId") (hasKey $value "url")) }} - curl -skf \ - --connect-timeout 60 \ - --max-time 60 \ - {{- if not $value.b64content }} - {{- if not $value.acceptHeader }} - -H "Accept: application/json" \ - {{- else }} - -H "Accept: {{ $value.acceptHeader }}" \ - {{- end }} - {{- if $value.token }} - -H "Authorization: token {{ $value.token }}" \ - {{- end }} - {{- if $value.bearerToken }} - -H "Authorization: Bearer {{ $value.bearerToken }}" \ - {{- end }} - {{- if $value.basic }} - -H "Authorization: Basic {{ $value.basic }}" \ - {{- end }} - {{- if $value.gitlabToken }} - -H "PRIVATE-TOKEN: {{ $value.gitlabToken }}" \ - {{- end }} - -H "Content-Type: application/json;charset=UTF-8" \ - {{- end }} - {{- $dpPath := "" -}} - {{- range $kd := (index $dashboardProviders "dashboardproviders.yaml").providers }} - {{- if eq $kd.name $provider }} - {{- $dpPath = $kd.options.path }} - {{- end }} - {{- end }} - {{- if $value.url }} - "{{ $value.url }}" \ - {{- else }} - "https://grafana.com/api/dashboards/{{ $value.gnetId }}/revisions/{{- if $value.revision -}}{{ $value.revision }}{{- else -}}1{{- end -}}/download" \ - {{- end }} - {{- if $value.datasource }} - {{- if kindIs "string" $value.datasource }} - | sed '/-- .* --/! s/"datasource":.*,/"datasource": "{{ $value.datasource }}",/g' \ - {{- end }} - {{- if kindIs "slice" $value.datasource }} - {{- range $value.datasource }} - | sed '/-- .* --/! s/${{"{"}}{{ .name }}}/{{ .value }}/g' \ - {{- end }} - {{- end }} - {{- end }} - {{- if $value.b64content }} - | base64 -d \ - {{- end }} - > "{{- if $dpPath -}}{{ $dpPath }}{{- else -}}/var/lib/grafana/dashboards/{{ $provider }}{{- end -}}/{{ $key }}.json" - {{ end }} - {{- end }} -{{- end }} -{{- end }} -{{- end -}} - -{{/* - Generate dashboard json config map data - */}} -{{- define "grafana.configDashboardProviderData" -}} -provider.yaml: |- - apiVersion: 1 - providers: - - name: '{{ .Values.sidecar.dashboards.provider.name }}' - orgId: {{ .Values.sidecar.dashboards.provider.orgid }} - {{- if not .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} - folder: '{{ .Values.sidecar.dashboards.provider.folder }}' - folderUid: '{{ .Values.sidecar.dashboards.provider.folderUid }}' - {{- end }} - type: {{ .Values.sidecar.dashboards.provider.type }} - disableDeletion: {{ .Values.sidecar.dashboards.provider.disableDelete }} - allowUiUpdates: {{ .Values.sidecar.dashboards.provider.allowUiUpdates }} - updateIntervalSeconds: {{ .Values.sidecar.dashboards.provider.updateIntervalSeconds | default 30 }} - options: - foldersFromFilesStructure: {{ .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} - path: {{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }} -{{- end -}} - -{{- define "grafana.secretsData" -}} -{{- if and (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) }} -admin-user: {{ .Values.adminUser | b64enc | quote }} -{{- if .Values.adminPassword }} -admin-password: {{ .Values.adminPassword | b64enc | quote }} -{{- else }} -admin-password: {{ include "grafana.password" . }} -{{- end }} -{{- end }} -{{- if not .Values.ldap.existingSecret }} -ldap-toml: {{ tpl .Values.ldap.config $ | b64enc | quote }} -{{- end }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_helpers.tpl deleted file mode 100644 index 68d2d815d8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_helpers.tpl +++ /dev/null @@ -1,305 +0,0 @@ -# Rancher -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "grafana.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 "grafana.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 "grafana.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create the name of the service account -*/}} -{{- define "grafana.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "grafana.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} - -{{- define "grafana.serviceAccountNameTest" -}} -{{- if .Values.serviceAccount.create }} -{{- default (print (include "grafana.fullname" .) "-test") .Values.serviceAccount.nameTest }} -{{- else }} -{{- default "default" .Values.serviceAccount.nameTest }} -{{- end }} -{{- end }} - -{{/* -Allow the release namespace to be overridden for multi-namespace deployments in combined charts -*/}} -{{- define "grafana.namespace" -}} -{{- if .Values.namespaceOverride }} -{{- .Values.namespaceOverride }} -{{- else }} -{{- .Release.Namespace }} -{{- end }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "grafana.labels" -}} -helm.sh/chart: {{ include "grafana.chart" . }} -{{ include "grafana.selectorLabels" . }} -{{- if or .Chart.AppVersion .Values.image.tag }} -app.kubernetes.io/version: {{ mustRegexReplaceAllLiteral "@sha.*" .Values.image.tag "" | default .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- with .Values.extraLabels }} -{{ toYaml . }} -{{- end }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "grafana.selectorLabels" -}} -app.kubernetes.io/name: {{ include "grafana.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "grafana.imageRenderer.labels" -}} -helm.sh/chart: {{ include "grafana.chart" . }} -{{ include "grafana.imageRenderer.selectorLabels" . }} -{{- if or .Chart.AppVersion .Values.image.tag }} -app.kubernetes.io/version: {{ mustRegexReplaceAllLiteral "@sha.*" .Values.image.tag "" | default .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels ImageRenderer -*/}} -{{- define "grafana.imageRenderer.selectorLabels" -}} -app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Looks if there's an existing secret and reuse its password. If not it generates -new password and use it. -*/}} -{{- define "grafana.password" -}} -{{- $secret := (lookup "v1" "Secret" (include "grafana.namespace" .) (include "grafana.fullname" .) ) }} -{{- if $secret }} -{{- index $secret "data" "admin-password" }} -{{- else }} -{{- (randAlphaNum 40) | b64enc | quote }} -{{- end }} -{{- end }} - -{{/* -Return the appropriate apiVersion for rbac. -*/}} -{{- define "grafana.rbac.apiVersion" -}} -{{- if $.Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }} -{{- print "rbac.authorization.k8s.io/v1" }} -{{- else }} -{{- print "rbac.authorization.k8s.io/v1beta1" }} -{{- end }} -{{- end }} - -{{/* -Return the appropriate apiVersion for ingress. -*/}} -{{- define "grafana.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 the appropriate apiVersion for Horizontal Pod Autoscaler. -*/}} -{{- define "grafana.hpa.apiVersion" -}} -{{- if .Capabilities.APIVersions.Has "autoscaling/v2" }} -{{- print "autoscaling/v2" }} -{{- else }} -{{- print "autoscaling/v2beta2" }} -{{- end }} -{{- end }} - -{{/* -Return the appropriate apiVersion for podDisruptionBudget. -*/}} -{{- define "grafana.podDisruptionBudget.apiVersion" -}} -{{- if $.Values.podDisruptionBudget.apiVersion }} -{{- print $.Values.podDisruptionBudget.apiVersion }} -{{- else if $.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} -{{- print "policy/v1" }} -{{- else }} -{{- print "policy/v1beta1" }} -{{- end }} -{{- end }} - -{{/* -Return if ingress is stable. -*/}} -{{- define "grafana.ingress.isStable" -}} -{{- eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1" }} -{{- end }} - -{{/* -Return if ingress supports ingressClassName. -*/}} -{{- define "grafana.ingress.supportsIngressClassName" -}} -{{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} -{{- end }} - -{{/* -Return if ingress supports pathType. -*/}} -{{- define "grafana.ingress.supportsPathType" -}} -{{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} -{{- end }} - -{{/* -Formats imagePullSecrets. Input is (dict "root" . "imagePullSecrets" .{specific imagePullSecrets}) -*/}} -{{- define "grafana.imagePullSecrets" -}} -{{- $root := .root }} -{{- range (concat .root.Values.global.imagePullSecrets .imagePullSecrets) }} -{{- if eq (typeOf .) "map[string]interface {}" }} -- {{ toYaml (dict "name" (tpl .name $root)) | trim }} -{{- else }} -- name: {{ tpl . $root }} -{{- end }} -{{- end }} -{{- end }} - - -{{/* - Checks whether or not the configSecret secret has to be created - */}} -{{- define "grafana.shouldCreateConfigSecret" -}} -{{- $secretFound := false -}} -{{- range $key, $value := .Values.datasources }} - {{- if hasKey $value "secret" }} - {{- $secretFound = true}} - {{- end }} -{{- end }} -{{- range $key, $value := .Values.notifiers }} - {{- if hasKey $value "secret" }} - {{- $secretFound = true}} - {{- end }} -{{- end }} -{{- range $key, $value := .Values.alerting }} - {{- if (or (hasKey $value "secret") (hasKey $value "secretFile")) }} - {{- $secretFound = true}} - {{- end }} -{{- end }} -{{- $secretFound}} -{{- end -}} - -{{/* - Checks whether the user is attempting to store secrets in plaintext - in the grafana.ini configmap -*/}} -{{/* grafana.assertNoLeakedSecrets checks for sensitive keys in values */}} -{{- define "grafana.assertNoLeakedSecrets" -}} - {{- $sensitiveKeysYaml := ` -sensitiveKeys: -- path: ["database", "password"] -- path: ["smtp", "password"] -- path: ["security", "secret_key"] -- path: ["security", "admin_password"] -- path: ["auth.basic", "password"] -- path: ["auth.ldap", "bind_password"] -- path: ["auth.google", "client_secret"] -- path: ["auth.github", "client_secret"] -- path: ["auth.gitlab", "client_secret"] -- path: ["auth.generic_oauth", "client_secret"] -- path: ["auth.okta", "client_secret"] -- path: ["auth.azuread", "client_secret"] -- path: ["auth.grafana_com", "client_secret"] -- path: ["auth.grafananet", "client_secret"] -- path: ["azure", "user_identity_client_secret"] -- path: ["unified_alerting", "ha_redis_password"] -- path: ["metrics", "basic_auth_password"] -- path: ["external_image_storage.s3", "secret_key"] -- path: ["external_image_storage.webdav", "password"] -- path: ["external_image_storage.azure_blob", "account_key"] -` | fromYaml -}} - {{- if $.Values.assertNoLeakedSecrets -}} - {{- $grafanaIni := index .Values "grafana.ini" -}} - {{- range $_, $secret := $sensitiveKeysYaml.sensitiveKeys -}} - {{- $currentMap := $grafanaIni -}} - {{- $shouldContinue := true -}} - {{- range $index, $elem := $secret.path -}} - {{- if and $shouldContinue (hasKey $currentMap $elem) -}} - {{- if eq (len $secret.path) (add1 $index) -}} - {{- if not (regexMatch "\\$(?:__(?:env|file|vault))?{[^}]+}" (index $currentMap $elem)) -}} - {{- fail (printf "Sensitive key '%s' should not be defined explicitly in values. Use variable expansion instead. You can disable this client-side validation by changing the value of assertNoLeakedSecrets." (join "." $secret.path)) -}} - {{- end -}} - {{- else -}} - {{- $currentMap = index $currentMap $elem -}} - {{- end -}} - {{- else -}} - {{- $shouldContinue = false -}} - {{- end -}} - {{- end -}} - {{- end -}} - {{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_pod.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_pod.tpl deleted file mode 100644 index 44526e5239..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/_pod.tpl +++ /dev/null @@ -1,1306 +0,0 @@ -{{- define "grafana.pod" -}} -{{- $sts := list "sts" "StatefulSet" "statefulset" -}} -{{- $root := . -}} -{{- with .Values.schedulerName }} -schedulerName: "{{ . }}" -{{- end }} -serviceAccountName: {{ include "grafana.serviceAccountName" . }} -automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} -{{- with .Values.securityContext }} -securityContext: - {{- toYaml . | nindent 2 }} -{{- end }} -{{- with .Values.hostAliases }} -hostAliases: - {{- toYaml . | nindent 2 }} -{{- end }} -{{- if .Values.dnsPolicy }} -dnsPolicy: {{ .Values.dnsPolicy }} -{{- end }} -{{- with .Values.dnsConfig }} -dnsConfig: - {{- toYaml . | nindent 2 }} -{{- end }} -{{- with .Values.priorityClassName }} -priorityClassName: {{ . }} -{{- end }} -{{- if ( or .Values.persistence.enabled .Values.dashboards .Values.extraInitContainers (and .Values.sidecar.alerts.enabled .Values.sidecar.alerts.initAlerts) (and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources) (and .Values.sidecar.notifiers.enabled .Values.sidecar.notifiers.initNotifiers)) }} -initContainers: -{{- end }} -{{- if ( and .Values.persistence.enabled .Values.initChownData.enabled ) }} - - name: init-chown-data - {{- $registry := include "system_default_registry" . | default .Values.initChownData.image.registry -}} - {{- if .Values.initChownData.image.sha }} - image: "{{ $registry }}{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}@sha256:{{ .Values.initChownData.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.initChownData.image.pullPolicy }} - {{- with .Values.initChownData.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - command: - - chown - - -R - - {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} - - /var/lib/grafana - {{- with .Values.initChownData.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: storage - mountPath: "/var/lib/grafana" - {{- with .Values.persistence.subPath }} - subPath: {{ tpl . $root }} - {{- end }} -{{- end }} -{{- if .Values.dashboards }} - - name: download-dashboards - {{- $registry := include "system_default_registry" . | default .Values.downloadDashboardsImage.registry -}} - {{- if .Values.downloadDashboardsImage.sha }} - image: "{{ $registry }}{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}@sha256:{{ .Values.downloadDashboardsImage.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.downloadDashboardsImage.pullPolicy }} - command: ["/bin/sh"] - args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh -x /etc/grafana/download_dashboards.sh" ] - {{- with .Values.downloadDashboards.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - env: - {{- range $key, $value := .Values.downloadDashboards.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- range $key, $value := .Values.downloadDashboards.envValueFrom }} - - name: {{ $key | quote }} - valueFrom: - {{- tpl (toYaml $value) $ | nindent 10 }} - {{- end }} - {{- with .Values.downloadDashboards.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.downloadDashboards.envFromSecret }} - envFrom: - - secretRef: - name: {{ tpl . $root }} - {{- end }} - volumeMounts: - - name: config - mountPath: "/etc/grafana/download_dashboards.sh" - subPath: download_dashboards.sh - - name: storage - mountPath: "/var/lib/grafana" - {{- with .Values.persistence.subPath }} - subPath: {{ tpl . $root }} - {{- end }} - {{- range .Values.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - readOnly: {{ .readOnly }} - {{- end }} -{{- end }} -{{- if and .Values.sidecar.alerts.enabled .Values.sidecar.alerts.initAlerts }} - - name: {{ include "grafana.name" . }}-init-sc-alerts - {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} - {{- if .Values.sidecar.image.sha }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - {{- range $key, $value := .Values.sidecar.alerts.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- if .Values.sidecar.alerts.ignoreAlreadyProcessed }} - - name: IGNORE_ALREADY_PROCESSED - value: "true" - {{- end }} - - name: METHOD - value: "LIST" - - name: LABEL - value: "{{ .Values.sidecar.alerts.label }}" - {{- with .Values.sidecar.alerts.labelValue }} - - name: LABEL_VALUE - value: {{ quote . }} - {{- end }} - {{- if or .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} - - name: LOG_LEVEL - value: {{ default .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} - {{- end }} - - name: FOLDER - value: "/etc/grafana/provisioning/alerting" - - name: RESOURCE - value: {{ quote .Values.sidecar.alerts.resource }} - {{- with .Values.sidecar.enableUniqueFilenames }} - - name: UNIQUE_FILENAMES - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.alerts.searchNamespace }} - - name: NAMESPACE - value: {{ . | join "," | quote }} - {{- end }} - {{- with .Values.sidecar.alerts.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: {{ quote . }} - {{- end }} - {{- with .Values.sidecar.alerts.script }} - - name: SCRIPT - value: {{ quote . }} - {{- end }} - {{- with .Values.sidecar.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: sc-alerts-volume - mountPath: "/etc/grafana/provisioning/alerting" - {{- with .Values.sidecar.alerts.extraMounts }} - {{- toYaml . | trim | nindent 6 }} - {{- end }} -{{- end }} -{{- if and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources }} - - name: {{ include "grafana.name" . }}-init-sc-datasources - {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} - {{- if .Values.sidecar.image.sha }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - {{- range $key, $value := .Values.sidecar.datasources.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- range $key, $value := .Values.sidecar.datasources.envValueFrom }} - - name: {{ $key | quote }} - valueFrom: - {{- tpl (toYaml $value) $ | nindent 10 }} - {{- end }} - {{- if .Values.sidecar.datasources.ignoreAlreadyProcessed }} - - name: IGNORE_ALREADY_PROCESSED - value: "true" - {{- end }} - - name: METHOD - value: "LIST" - - name: LABEL - value: "{{ .Values.sidecar.datasources.label }}" - {{- with .Values.sidecar.datasources.labelValue }} - - name: LABEL_VALUE - value: {{ quote . }} - {{- end }} - {{- if or .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} - - name: LOG_LEVEL - value: {{ default .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} - {{- end }} - - name: FOLDER - value: "/etc/grafana/provisioning/datasources" - - name: RESOURCE - value: {{ quote .Values.sidecar.datasources.resource }} - {{- with .Values.sidecar.enableUniqueFilenames }} - - name: UNIQUE_FILENAMES - value: "{{ . }}" - {{- end }} - {{- if .Values.sidecar.datasources.searchNamespace }} - - name: NAMESPACE - value: "{{ tpl (.Values.sidecar.datasources.searchNamespace | join ",") . }}" - {{- end }} - {{- with .Values.sidecar.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: sc-datasources-volume - mountPath: "/etc/grafana/provisioning/datasources" -{{- end }} -{{- if and .Values.sidecar.notifiers.enabled .Values.sidecar.notifiers.initNotifiers }} - - name: {{ include "grafana.name" . }}-init-sc-notifiers - {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} - {{- if .Values.sidecar.image.sha }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - {{- range $key, $value := .Values.sidecar.notifiers.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- if .Values.sidecar.notifiers.ignoreAlreadyProcessed }} - - name: IGNORE_ALREADY_PROCESSED - value: "true" - {{- end }} - - name: METHOD - value: LIST - - name: LABEL - value: "{{ .Values.sidecar.notifiers.label }}" - {{- with .Values.sidecar.notifiers.labelValue }} - - name: LABEL_VALUE - value: {{ quote . }} - {{- end }} - {{- if or .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} - - name: LOG_LEVEL - value: {{ default .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} - {{- end }} - - name: FOLDER - value: "/etc/grafana/provisioning/notifiers" - - name: RESOURCE - value: {{ quote .Values.sidecar.notifiers.resource }} - {{- with .Values.sidecar.enableUniqueFilenames }} - - name: UNIQUE_FILENAMES - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.notifiers.searchNamespace }} - - name: NAMESPACE - value: "{{ tpl (. | join ",") $root }}" - {{- end }} - {{- with .Values.sidecar.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: sc-notifiers-volume - mountPath: "/etc/grafana/provisioning/notifiers" -{{- end}} -{{- with .Values.extraInitContainers }} - {{- tpl (toYaml .) $root | nindent 2 }} -{{- end }} -{{- if or .Values.image.pullSecrets .Values.global.imagePullSecrets }} -imagePullSecrets: - {{- include "grafana.imagePullSecrets" (dict "root" $root "imagePullSecrets" .Values.image.pullSecrets) | nindent 2 }} -{{- end }} -{{- if not .Values.enableKubeBackwardCompatibility }} -enableServiceLinks: {{ .Values.enableServiceLinks }} -{{- end }} -containers: -{{- if and .Values.sidecar.alerts.enabled (not .Values.sidecar.alerts.initAlerts) }} - - name: {{ include "grafana.name" . }}-sc-alerts - {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} - {{- if .Values.sidecar.image.sha }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - {{- range $key, $value := .Values.sidecar.alerts.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- if .Values.sidecar.alerts.ignoreAlreadyProcessed }} - - name: IGNORE_ALREADY_PROCESSED - value: "true" - {{- end }} - - name: METHOD - value: {{ .Values.sidecar.alerts.watchMethod }} - - name: LABEL - value: "{{ .Values.sidecar.alerts.label }}" - {{- with .Values.sidecar.alerts.labelValue }} - - name: LABEL_VALUE - value: {{ quote . }} - {{- end }} - {{- if or .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} - - name: LOG_LEVEL - value: {{ default .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} - {{- end }} - - name: FOLDER - value: "/etc/grafana/provisioning/alerting" - - name: RESOURCE - value: {{ quote .Values.sidecar.alerts.resource }} - {{- with .Values.sidecar.enableUniqueFilenames }} - - name: UNIQUE_FILENAMES - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.alerts.searchNamespace }} - - name: NAMESPACE - value: {{ . | join "," | quote }} - {{- end }} - {{- with .Values.sidecar.alerts.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: {{ quote . }} - {{- end }} - {{- with .Values.sidecar.alerts.script }} - - name: SCRIPT - value: {{ quote . }} - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_USERNAME - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.userKey | default "admin-user" }} - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_PASSWORD - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.passwordKey | default "admin-password" }} - {{- end }} - {{- if not .Values.sidecar.alerts.skipReload }} - - name: REQ_URL - value: {{ .Values.sidecar.alerts.reloadURL }} - - name: REQ_METHOD - value: POST - {{- end }} - {{- if .Values.sidecar.alerts.watchServerTimeout }} - {{- if ne .Values.sidecar.alerts.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.alerts.watchServerTimeout with .Values.sidecar.alerts.watchMethod %s" .Values.sidecar.alerts.watchMethod) }} - {{- end }} - - name: WATCH_SERVER_TIMEOUT - value: "{{ .Values.sidecar.alerts.watchServerTimeout }}" - {{- end }} - {{- if .Values.sidecar.alerts.watchClientTimeout }} - {{- if ne .Values.sidecar.alerts.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.alerts.watchClientTimeout with .Values.sidecar.alerts.watchMethod %s" .Values.sidecar.alerts.watchMethod) }} - {{- end }} - - name: WATCH_CLIENT_TIMEOUT - value: "{{ .Values.sidecar.alerts.watchClientTimeout }}" - {{- end }} - {{- with .Values.sidecar.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: sc-alerts-volume - mountPath: "/etc/grafana/provisioning/alerting" - {{- with .Values.sidecar.alerts.extraMounts }} - {{- toYaml . | trim | nindent 6 }} - {{- end }} -{{- end}} -{{- if .Values.sidecar.dashboards.enabled }} - - name: {{ include "grafana.name" . }}-sc-dashboard - {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} - {{- if .Values.sidecar.image.sha }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - {{- range $key, $value := .Values.sidecar.dashboards.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- range $key, $value := .Values.sidecar.dashboards.envValueFrom }} - - name: {{ $key | quote }} - valueFrom: - {{- tpl (toYaml $value) $ | nindent 10 }} - {{- end }} - {{- if .Values.sidecar.dashboards.ignoreAlreadyProcessed }} - - name: IGNORE_ALREADY_PROCESSED - value: "true" - {{- end }} - - name: METHOD - value: {{ .Values.sidecar.dashboards.watchMethod }} - - name: LABEL - value: "{{ .Values.sidecar.dashboards.label }}" - {{- with .Values.sidecar.dashboards.labelValue }} - - name: LABEL_VALUE - value: {{ quote . }} - {{- end }} - {{- if or .Values.sidecar.logLevel .Values.sidecar.dashboards.logLevel }} - - name: LOG_LEVEL - value: {{ default .Values.sidecar.logLevel .Values.sidecar.dashboards.logLevel }} - {{- end }} - - name: FOLDER - value: "{{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}" - - name: RESOURCE - value: {{ quote .Values.sidecar.dashboards.resource }} - {{- with .Values.sidecar.enableUniqueFilenames }} - - name: UNIQUE_FILENAMES - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.dashboards.searchNamespace }} - - name: NAMESPACE - value: "{{ tpl (. | join ",") $root }}" - {{- end }} - {{- with .Values.sidecar.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.dashboards.folderAnnotation }} - - name: FOLDER_ANNOTATION - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.dashboards.script }} - - name: SCRIPT - value: "{{ . }}" - {{- end }} - {{- if not .Values.sidecar.dashboards.skipReload }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_USERNAME - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.userKey | default "admin-user" }} - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_PASSWORD - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.passwordKey | default "admin-password" }} - {{- end }} - - name: REQ_URL - value: {{ .Values.sidecar.dashboards.reloadURL }} - - name: REQ_METHOD - value: POST - {{- end }} - {{- if .Values.sidecar.dashboards.watchServerTimeout }} - {{- if ne .Values.sidecar.dashboards.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.dashboards.watchServerTimeout with .Values.sidecar.dashboards.watchMethod %s" .Values.sidecar.dashboards.watchMethod) }} - {{- end }} - - name: WATCH_SERVER_TIMEOUT - value: "{{ .Values.sidecar.dashboards.watchServerTimeout }}" - {{- end }} - {{- if .Values.sidecar.dashboards.watchClientTimeout }} - {{- if ne .Values.sidecar.dashboards.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.dashboards.watchClientTimeout with .Values.sidecar.dashboards.watchMethod %s" .Values.sidecar.dashboards.watchMethod) }} - {{- end }} - - name: WATCH_CLIENT_TIMEOUT - value: {{ .Values.sidecar.dashboards.watchClientTimeout | quote }} - {{- end }} - {{- with .Values.sidecar.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: sc-dashboard-volume - mountPath: {{ .Values.sidecar.dashboards.folder | quote }} - {{- with .Values.sidecar.dashboards.extraMounts }} - {{- toYaml . | trim | nindent 6 }} - {{- end }} -{{- end}} -{{- if and .Values.sidecar.datasources.enabled (not .Values.sidecar.datasources.initDatasources) }} - - name: {{ include "grafana.name" . }}-sc-datasources - {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} - {{- if .Values.sidecar.image.sha }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - {{- range $key, $value := .Values.sidecar.datasources.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- range $key, $value := .Values.sidecar.datasources.envValueFrom }} - - name: {{ $key | quote }} - valueFrom: - {{- tpl (toYaml $value) $ | nindent 10 }} - {{- end }} - {{- if .Values.sidecar.datasources.ignoreAlreadyProcessed }} - - name: IGNORE_ALREADY_PROCESSED - value: "true" - {{- end }} - - name: METHOD - value: {{ .Values.sidecar.datasources.watchMethod }} - - name: LABEL - value: "{{ .Values.sidecar.datasources.label }}" - {{- with .Values.sidecar.datasources.labelValue }} - - name: LABEL_VALUE - value: {{ quote . }} - {{- end }} - {{- if or .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} - - name: LOG_LEVEL - value: {{ default .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} - {{- end }} - - name: FOLDER - value: "/etc/grafana/provisioning/datasources" - - name: RESOURCE - value: {{ quote .Values.sidecar.datasources.resource }} - {{- with .Values.sidecar.enableUniqueFilenames }} - - name: UNIQUE_FILENAMES - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.datasources.searchNamespace }} - - name: NAMESPACE - value: "{{ tpl (. | join ",") $root }}" - {{- end }} - {{- if .Values.sidecar.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: "{{ .Values.sidecar.skipTlsVerify }}" - {{- end }} - {{- if .Values.sidecar.datasources.script }} - - name: SCRIPT - value: "{{ .Values.sidecar.datasources.script }}" - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_USERNAME - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.userKey | default "admin-user" }} - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_PASSWORD - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.passwordKey | default "admin-password" }} - {{- end }} - {{- if not .Values.sidecar.datasources.skipReload }} - - name: REQ_URL - value: {{ .Values.sidecar.datasources.reloadURL }} - - name: REQ_METHOD - value: POST - {{- end }} - {{- if .Values.sidecar.datasources.watchServerTimeout }} - {{- if ne .Values.sidecar.datasources.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.datasources.watchServerTimeout with .Values.sidecar.datasources.watchMethod %s" .Values.sidecar.datasources.watchMethod) }} - {{- end }} - - name: WATCH_SERVER_TIMEOUT - value: "{{ .Values.sidecar.datasources.watchServerTimeout }}" - {{- end }} - {{- if .Values.sidecar.datasources.watchClientTimeout }} - {{- if ne .Values.sidecar.datasources.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.datasources.watchClientTimeout with .Values.sidecar.datasources.watchMethod %s" .Values.sidecar.datasources.watchMethod) }} - {{- end }} - - name: WATCH_CLIENT_TIMEOUT - value: "{{ .Values.sidecar.datasources.watchClientTimeout }}" - {{- end }} - {{- with .Values.sidecar.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: sc-datasources-volume - mountPath: "/etc/grafana/provisioning/datasources" -{{- end}} -{{- if .Values.sidecar.notifiers.enabled }} - - name: {{ include "grafana.name" . }}-sc-notifiers - {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} - {{- if .Values.sidecar.image.sha }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - {{- range $key, $value := .Values.sidecar.notifiers.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- if .Values.sidecar.notifiers.ignoreAlreadyProcessed }} - - name: IGNORE_ALREADY_PROCESSED - value: "true" - {{- end }} - - name: METHOD - value: {{ .Values.sidecar.notifiers.watchMethod }} - - name: LABEL - value: "{{ .Values.sidecar.notifiers.label }}" - {{- with .Values.sidecar.notifiers.labelValue }} - - name: LABEL_VALUE - value: {{ quote . }} - {{- end }} - {{- if or .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} - - name: LOG_LEVEL - value: {{ default .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} - {{- end }} - - name: FOLDER - value: "/etc/grafana/provisioning/notifiers" - - name: RESOURCE - value: {{ quote .Values.sidecar.notifiers.resource }} - {{- if .Values.sidecar.enableUniqueFilenames }} - - name: UNIQUE_FILENAMES - value: "{{ .Values.sidecar.enableUniqueFilenames }}" - {{- end }} - {{- with .Values.sidecar.notifiers.searchNamespace }} - - name: NAMESPACE - value: "{{ tpl (. | join ",") $root }}" - {{- end }} - {{- with .Values.sidecar.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: "{{ . }}" - {{- end }} - {{- if .Values.sidecar.notifiers.script }} - - name: SCRIPT - value: "{{ .Values.sidecar.notifiers.script }}" - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_USERNAME - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.userKey | default "admin-user" }} - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_PASSWORD - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.passwordKey | default "admin-password" }} - {{- end }} - {{- if not .Values.sidecar.notifiers.skipReload }} - - name: REQ_URL - value: {{ .Values.sidecar.notifiers.reloadURL }} - - name: REQ_METHOD - value: POST - {{- end }} - {{- if .Values.sidecar.notifiers.watchServerTimeout }} - {{- if ne .Values.sidecar.notifiers.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.notifiers.watchServerTimeout with .Values.sidecar.notifiers.watchMethod %s" .Values.sidecar.notifiers.watchMethod) }} - {{- end }} - - name: WATCH_SERVER_TIMEOUT - value: "{{ .Values.sidecar.notifiers.watchServerTimeout }}" - {{- end }} - {{- if .Values.sidecar.notifiers.watchClientTimeout }} - {{- if ne .Values.sidecar.notifiers.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.notifiers.watchClientTimeout with .Values.sidecar.notifiers.watchMethod %s" .Values.sidecar.notifiers.watchMethod) }} - {{- end }} - - name: WATCH_CLIENT_TIMEOUT - value: "{{ .Values.sidecar.notifiers.watchClientTimeout }}" - {{- end }} - {{- with .Values.sidecar.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: sc-notifiers-volume - mountPath: "/etc/grafana/provisioning/notifiers" -{{- end}} -{{- if .Values.sidecar.plugins.enabled }} - - name: {{ include "grafana.name" . }}-sc-plugins - {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} - {{- if .Values.sidecar.image.sha }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} - env: - {{- range $key, $value := .Values.sidecar.plugins.env }} - - name: "{{ $key }}" - value: "{{ $value }}" - {{- end }} - {{- if .Values.sidecar.plugins.ignoreAlreadyProcessed }} - - name: IGNORE_ALREADY_PROCESSED - value: "true" - {{- end }} - - name: METHOD - value: {{ .Values.sidecar.plugins.watchMethod }} - - name: LABEL - value: "{{ .Values.sidecar.plugins.label }}" - {{- if .Values.sidecar.plugins.labelValue }} - - name: LABEL_VALUE - value: {{ quote .Values.sidecar.plugins.labelValue }} - {{- end }} - {{- if or .Values.sidecar.logLevel .Values.sidecar.plugins.logLevel }} - - name: LOG_LEVEL - value: {{ default .Values.sidecar.logLevel .Values.sidecar.plugins.logLevel }} - {{- end }} - - name: FOLDER - value: "/etc/grafana/provisioning/plugins" - - name: RESOURCE - value: {{ quote .Values.sidecar.plugins.resource }} - {{- with .Values.sidecar.enableUniqueFilenames }} - - name: UNIQUE_FILENAMES - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.plugins.searchNamespace }} - - name: NAMESPACE - value: "{{ tpl (. | join ",") $root }}" - {{- end }} - {{- with .Values.sidecar.plugins.script }} - - name: SCRIPT - value: "{{ . }}" - {{- end }} - {{- with .Values.sidecar.skipTlsVerify }} - - name: SKIP_TLS_VERIFY - value: "{{ . }}" - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_USERNAME - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.userKey | default "admin-user" }} - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: REQ_PASSWORD - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.passwordKey | default "admin-password" }} - {{- end }} - {{- if not .Values.sidecar.plugins.skipReload }} - - name: REQ_URL - value: {{ .Values.sidecar.plugins.reloadURL }} - - name: REQ_METHOD - value: POST - {{- end }} - {{- if .Values.sidecar.plugins.watchServerTimeout }} - {{- if ne .Values.sidecar.plugins.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.plugins.watchServerTimeout with .Values.sidecar.plugins.watchMethod %s" .Values.sidecar.plugins.watchMethod) }} - {{- end }} - - name: WATCH_SERVER_TIMEOUT - value: "{{ .Values.sidecar.plugins.watchServerTimeout }}" - {{- end }} - {{- if .Values.sidecar.plugins.watchClientTimeout }} - {{- if ne .Values.sidecar.plugins.watchMethod "WATCH" }} - {{- fail (printf "Cannot use .Values.sidecar.plugins.watchClientTimeout with .Values.sidecar.plugins.watchMethod %s" .Values.sidecar.plugins.watchMethod) }} - {{- end }} - - name: WATCH_CLIENT_TIMEOUT - value: "{{ .Values.sidecar.plugins.watchClientTimeout }}" - {{- end }} - {{- with .Values.sidecar.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.sidecar.securityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: sc-plugins-volume - mountPath: "/etc/grafana/provisioning/plugins" -{{- end}} - - name: {{ .Chart.Name }} - {{- $registry := include "system_default_registry" . | default .Values.image.registry -}} - {{- if .Values.image.sha }} - image: "{{ $registry }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - {{- end }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - {{- if .Values.command }} - command: - {{- range .Values.command }} - - {{ . | quote }} - {{- end }} - {{- end }} - {{- if .Values.args }} - args: - {{- range .Values.args }} - - {{ . | quote }} - {{- end }} - {{- end }} - {{- with .Values.containerSecurityContext }} - securityContext: - {{- toYaml . | nindent 6 }} - {{- end }} - volumeMounts: - - name: config - mountPath: "/etc/grafana/grafana.ini" - subPath: grafana.ini - {{- if .Values.ldap.enabled }} - - name: ldap - mountPath: "/etc/grafana/ldap.toml" - subPath: ldap.toml - {{- end }} - {{- range .Values.extraConfigmapMounts }} - - name: {{ tpl .name $root }} - mountPath: {{ tpl .mountPath $root }} - subPath: {{ tpl (.subPath | default "") $root }} - readOnly: {{ .readOnly }} - {{- end }} - - name: storage - mountPath: "/var/lib/grafana" - {{- with .Values.persistence.subPath }} - subPath: {{ tpl . $root }} - {{- end }} - {{- with .Values.dashboards }} - {{- range $provider, $dashboards := . }} - {{- range $key, $value := $dashboards }} - {{- if (or (hasKey $value "json") (hasKey $value "file")) }} - - name: dashboards-{{ $provider }} - mountPath: "/var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json" - subPath: "{{ $key }}.json" - {{- end }} - {{- end }} - {{- end }} - {{- end }} - {{- with .Values.dashboardsConfigMaps }} - {{- range (keys . | sortAlpha) }} - - name: dashboards-{{ . }} - mountPath: "/var/lib/grafana/dashboards/{{ . }}" - {{- end }} - {{- end }} - {{- with .Values.datasources }} - {{- $datasources := . }} - {{- range (keys . | sortAlpha) }} - {{- if (or (hasKey (index $datasources .) "secret")) }} {{/*check if current datasource should be handeled as secret */}} - - name: config-secret - mountPath: "/etc/grafana/provisioning/datasources/{{ . }}" - subPath: {{ . | quote }} - {{- else }} - - name: config - mountPath: "/etc/grafana/provisioning/datasources/{{ . }}" - subPath: {{ . | quote }} - {{- end }} - {{- end }} - {{- end }} - {{- with .Values.notifiers }} - {{- $notifiers := . }} - {{- range (keys . | sortAlpha) }} - {{- if (or (hasKey (index $notifiers .) "secret")) }} {{/*check if current notifier should be handeled as secret */}} - - name: config-secret - mountPath: "/etc/grafana/provisioning/notifiers/{{ . }}" - subPath: {{ . | quote }} - {{- else }} - - name: config - mountPath: "/etc/grafana/provisioning/notifiers/{{ . }}" - subPath: {{ . | quote }} - {{- end }} - {{- end }} - {{- end }} - {{- with .Values.alerting }} - {{- $alertingmap := .}} - {{- range (keys . | sortAlpha) }} - {{- if (or (hasKey (index $.Values.alerting .) "secret") (hasKey (index $.Values.alerting .) "secretFile")) }} {{/*check if current alerting entry should be handeled as secret */}} - - name: config-secret - mountPath: "/etc/grafana/provisioning/alerting/{{ . }}" - subPath: {{ . | quote }} - {{- else }} - - name: config - mountPath: "/etc/grafana/provisioning/alerting/{{ . }}" - subPath: {{ . | quote }} - {{- end }} - {{- end }} - {{- end }} - {{- with .Values.dashboardProviders }} - {{- range (keys . | sortAlpha) }} - - name: config - mountPath: "/etc/grafana/provisioning/dashboards/{{ . }}" - subPath: {{ . | quote }} - {{- end }} - {{- end }} - {{- with .Values.sidecar.alerts.enabled }} - - name: sc-alerts-volume - mountPath: "/etc/grafana/provisioning/alerting" - {{- end}} - {{- if .Values.sidecar.dashboards.enabled }} - - name: sc-dashboard-volume - mountPath: {{ .Values.sidecar.dashboards.folder | quote }} - {{- if .Values.sidecar.dashboards.SCProvider }} - - name: sc-dashboard-provider - mountPath: "/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml" - subPath: provider.yaml - {{- end}} - {{- end}} - {{- if .Values.sidecar.datasources.enabled }} - - name: sc-datasources-volume - mountPath: "/etc/grafana/provisioning/datasources" - {{- end}} - {{- if .Values.sidecar.plugins.enabled }} - - name: sc-plugins-volume - mountPath: "/etc/grafana/provisioning/plugins" - {{- end}} - {{- if .Values.sidecar.notifiers.enabled }} - - name: sc-notifiers-volume - mountPath: "/etc/grafana/provisioning/notifiers" - {{- end}} - {{- range .Values.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - readOnly: {{ .readOnly }} - subPath: {{ .subPath | default "" }} - {{- end }} - {{- range .Values.extraVolumeMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath | default "" }} - readOnly: {{ .readOnly }} - {{- end }} - {{- range .Values.extraEmptyDirMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - {{- end }} - ports: - - name: {{ .Values.podPortName }} - containerPort: {{ .Values.service.targetPort }} - protocol: TCP - - name: {{ .Values.gossipPortName }}-tcp - containerPort: 9094 - protocol: TCP - - name: {{ .Values.gossipPortName }}-udp - containerPort: 9094 - protocol: UDP - env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: GF_SECURITY_ADMIN_USER - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.userKey | default "admin-user" }} - {{- end }} - {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - - name: GF_SECURITY_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} - key: {{ .Values.admin.passwordKey | default "admin-password" }} - {{- end }} - {{- if .Values.plugins }} - - name: GF_INSTALL_PLUGINS - valueFrom: - configMapKeyRef: - name: {{ include "grafana.fullname" . }} - key: plugins - {{- end }} - {{- if .Values.smtp.existingSecret }} - - name: GF_SMTP_USER - valueFrom: - secretKeyRef: - name: {{ .Values.smtp.existingSecret }} - key: {{ .Values.smtp.userKey | default "user" }} - - name: GF_SMTP_PASSWORD - valueFrom: - secretKeyRef: - name: {{ .Values.smtp.existingSecret }} - key: {{ .Values.smtp.passwordKey | default "password" }} - {{- end }} - {{- if .Values.imageRenderer.enabled }} - - name: GF_RENDERING_SERVER_URL - value: http://{{ include "grafana.fullname" . }}-image-renderer.{{ include "grafana.namespace" . }}:{{ .Values.imageRenderer.service.port }}/render - - name: GF_RENDERING_CALLBACK_URL - value: {{ .Values.imageRenderer.grafanaProtocol }}://{{ include "grafana.fullname" . }}.{{ include "grafana.namespace" . }}:{{ .Values.service.port }}/{{ .Values.imageRenderer.grafanaSubPath }} - {{- end }} - - name: GF_PATHS_DATA - value: {{ (get .Values "grafana.ini").paths.data }} - - name: GF_PATHS_LOGS - value: {{ (get .Values "grafana.ini").paths.logs }} - - name: GF_PATHS_PLUGINS - value: {{ (get .Values "grafana.ini").paths.plugins }} - - name: GF_PATHS_PROVISIONING - value: {{ (get .Values "grafana.ini").paths.provisioning }} - {{- range $key, $value := .Values.envValueFrom }} - - name: {{ $key | quote }} - valueFrom: - {{- tpl (toYaml $value) $ | nindent 10 }} - {{- end }} - {{- range $key, $value := .Values.env }} - - name: "{{ tpl $key $ }}" - value: "{{ tpl (print $value) $ }}" - {{- end }} - {{- if or .Values.envFromSecret (or .Values.envRenderSecret .Values.envFromSecrets) .Values.envFromConfigMaps }} - envFrom: - {{- if .Values.envFromSecret }} - - secretRef: - name: {{ tpl .Values.envFromSecret . }} - {{- end }} - {{- if .Values.envRenderSecret }} - - secretRef: - name: {{ include "grafana.fullname" . }}-env - {{- end }} - {{- range .Values.envFromSecrets }} - - secretRef: - name: {{ tpl .name $ }} - optional: {{ .optional | default false }} - {{- if .prefix }} - prefix: {{ tpl .prefix $ }} - {{- end }} - {{- end }} - {{- range .Values.envFromConfigMaps }} - - configMapRef: - name: {{ tpl .name $ }} - optional: {{ .optional | default false }} - {{- if .prefix }} - prefix: {{ tpl .prefix $ }} - {{- end }} - {{- end }} - {{- end }} - {{- with .Values.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.lifecycleHooks }} - lifecycle: - {{- tpl (toYaml .) $root | nindent 6 }} - {{- end }} - {{- with .Values.resources }} - resources: - {{- toYaml . | nindent 6 }} - {{- end }} -{{- with .Values.extraContainers }} - {{- tpl . $ | nindent 2 }} -{{- end }} -nodeSelector: {{ include "linux-node-selector" . | nindent 2 }} -{{- with .Values.nodeSelector }} - {{- toYaml . | nindent 2 }} -{{- end }} -{{- with .Values.affinity }} -affinity: - {{- tpl (toYaml .) $root | nindent 2 }} -{{- end }} -{{- with .Values.topologySpreadConstraints }} -topologySpreadConstraints: - {{- toYaml . | nindent 2 }} -{{- end }} -tolerations: {{ include "linux-node-tolerations" . | nindent 2 }} -{{- with .Values.tolerations }} - {{- toYaml . | nindent 2 }} -{{- end }} -volumes: - - name: config - configMap: - name: {{ include "grafana.fullname" . }} - {{- $createConfigSecret := eq (include "grafana.shouldCreateConfigSecret" .) "true" -}} - {{- if and .Values.createConfigmap $createConfigSecret }} - - name: config-secret - secret: - secretName: {{ include "grafana.fullname" . }}-config-secret - {{- end }} - {{- range .Values.extraConfigmapMounts }} - - name: {{ tpl .name $root }} - configMap: - name: {{ tpl .configMap $root }} - {{- with .items }} - items: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - {{- if .Values.dashboards }} - {{- range (keys .Values.dashboards | sortAlpha) }} - - name: dashboards-{{ . }} - configMap: - name: {{ include "grafana.fullname" $ }}-dashboards-{{ . }} - {{- end }} - {{- end }} - {{- if .Values.dashboardsConfigMaps }} - {{- range $provider, $name := .Values.dashboardsConfigMaps }} - - name: dashboards-{{ $provider }} - configMap: - name: {{ tpl $name $root }} - {{- end }} - {{- end }} - {{- if .Values.ldap.enabled }} - - name: ldap - secret: - {{- if .Values.ldap.existingSecret }} - secretName: {{ .Values.ldap.existingSecret }} - {{- else }} - secretName: {{ include "grafana.fullname" . }} - {{- end }} - items: - - key: ldap-toml - path: ldap.toml - {{- end }} - {{- if and .Values.persistence.enabled (eq .Values.persistence.type "pvc") }} - - name: storage - persistentVolumeClaim: - claimName: {{ tpl (.Values.persistence.existingClaim | default (include "grafana.fullname" .)) . }} - {{- else if and .Values.persistence.enabled (has .Values.persistence.type $sts) }} - {{/* nothing */}} - {{- else }} - - name: storage - {{- if .Values.persistence.inMemory.enabled }} - emptyDir: - medium: Memory - {{- with .Values.persistence.inMemory.sizeLimit }} - sizeLimit: {{ . }} - {{- end }} - {{- else }} - emptyDir: {} - {{- end }} - {{- end }} - {{- if .Values.sidecar.alerts.enabled }} - - name: sc-alerts-volume - emptyDir: - {{- with .Values.sidecar.alerts.sizeLimit }} - sizeLimit: {{ . }} - {{- else }} - {} - {{- end }} - {{- end }} - {{- if .Values.sidecar.dashboards.enabled }} - - name: sc-dashboard-volume - emptyDir: - {{- with .Values.sidecar.dashboards.sizeLimit }} - sizeLimit: {{ . }} - {{- else }} - {} - {{- end }} - {{- if .Values.sidecar.dashboards.SCProvider }} - - name: sc-dashboard-provider - configMap: - name: {{ include "grafana.fullname" . }}-config-dashboards - {{- end }} - {{- end }} - {{- if .Values.sidecar.datasources.enabled }} - - name: sc-datasources-volume - emptyDir: - {{- with .Values.sidecar.datasources.sizeLimit }} - sizeLimit: {{ . }} - {{- else }} - {} - {{- end }} - {{- end }} - {{- if .Values.sidecar.plugins.enabled }} - - name: sc-plugins-volume - emptyDir: - {{- with .Values.sidecar.plugins.sizeLimit }} - sizeLimit: {{ . }} - {{- else }} - {} - {{- end }} - {{- end }} - {{- if .Values.sidecar.notifiers.enabled }} - - name: sc-notifiers-volume - emptyDir: - {{- with .Values.sidecar.notifiers.sizeLimit }} - sizeLimit: {{ . }} - {{- else }} - {} - {{- end }} - {{- end }} - {{- range .Values.extraSecretMounts }} - {{- if .secretName }} - - name: {{ .name }} - secret: - secretName: {{ .secretName }} - defaultMode: {{ .defaultMode }} - {{- with .items }} - items: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- else if .projected }} - - name: {{ .name }} - projected: - {{- toYaml .projected | nindent 6 }} - {{- else if .csi }} - - name: {{ .name }} - csi: - {{- toYaml .csi | nindent 6 }} - {{- end }} - {{- end }} - {{- range .Values.extraVolumes }} - - name: {{ .name }} - {{- if .existingClaim }} - persistentVolumeClaim: - claimName: {{ .existingClaim }} - {{- else if .hostPath }} - hostPath: - {{ toYaml .hostPath | nindent 6 }} - {{- else if .csi }} - csi: - {{- toYaml .csi | nindent 6 }} - {{- else if .configMap }} - configMap: - {{- toYaml .configMap | nindent 6 }} - {{- else if .emptyDir }} - emptyDir: - {{- toYaml .emptyDir | nindent 6 }} - {{- else }} - emptyDir: {} - {{- end }} - {{- end }} - {{- range .Values.extraEmptyDirMounts }} - - name: {{ .name }} - emptyDir: {} - {{- end }} - {{- with .Values.extraContainerVolumes }} - {{- tpl (toYaml .) $root | nindent 2 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/clusterrole.yaml deleted file mode 100644 index 3af4b62b63..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/clusterrole.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- if and .Values.rbac.create (or (not .Values.rbac.namespaced) .Values.rbac.extraClusterRoleRules) (not .Values.rbac.useExistingClusterRole) }} -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} - name: {{ include "grafana.fullname" . }}-clusterrole -{{- if or .Values.sidecar.dashboards.enabled .Values.rbac.extraClusterRoleRules .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled .Values.sidecar.alerts.enabled }} -rules: - {{- if or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled .Values.sidecar.alerts.enabled }} - - apiGroups: [""] # "" indicates the core API group - resources: ["configmaps", "secrets"] - verbs: ["get", "watch", "list"] - {{- end}} - {{- with .Values.rbac.extraClusterRoleRules }} - {{- toYaml . | nindent 2 }} - {{- end}} -{{- else }} -rules: [] -{{- end}} -{{- end}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/clusterrolebinding.yaml deleted file mode 100644 index bda9431a2c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/clusterrolebinding.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if and .Values.rbac.create (or (not .Values.rbac.namespaced) .Values.rbac.extraClusterRoleRules) }} -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ include "grafana.fullname" . }}-clusterrolebinding - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -subjects: - - kind: ServiceAccount - name: {{ include "grafana.serviceAccountName" . }} - namespace: {{ include "grafana.namespace" . }} -roleRef: - kind: ClusterRole - {{- if .Values.rbac.useExistingClusterRole }} - name: {{ .Values.rbac.useExistingClusterRole }} - {{- else }} - name: {{ include "grafana.fullname" . }}-clusterrole - {{- end }} - apiGroup: rbac.authorization.k8s.io -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configSecret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configSecret.yaml deleted file mode 100644 index 55574b9bbc..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configSecret.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- $createConfigSecret := eq (include "grafana.shouldCreateConfigSecret" .) "true" -}} -{{- if and .Values.createConfigmap $createConfigSecret }} -{{- $files := .Files }} -{{- $root := . -}} -apiVersion: v1 -kind: Secret -metadata: - name: "{{ include "grafana.fullname" . }}-config-secret" - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -data: -{{- range $key, $value := .Values.alerting }} - {{- if (hasKey $value "secretFile") }} - {{- $key | nindent 2 }}: - {{- toYaml ( $files.Get $value.secretFile ) | b64enc | nindent 4}} - {{/* as of https://helm.sh/docs/chart_template_guide/accessing_files/ this will only work if you fork this chart and add files to it*/}} - {{- end }} -{{- end }} -stringData: -{{- range $key, $value := .Values.datasources }} -{{- if (hasKey $value "secret") }} -{{- $key | nindent 2 }}: | - {{- tpl (toYaml $value.secret | nindent 4) $root }} -{{- end }} -{{- end }} -{{- range $key, $value := .Values.notifiers }} -{{- if (hasKey $value "secret") }} -{{- $key | nindent 2 }}: | - {{- tpl (toYaml $value.secret | nindent 4) $root }} -{{- end }} -{{- end }} -{{- range $key, $value := .Values.alerting }} -{{ if (hasKey $value "secret") }} - {{- $key | nindent 2 }}: | - {{- tpl (toYaml $value.secret | nindent 4) $root }} - {{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configmap-dashboard-provider.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configmap-dashboard-provider.yaml deleted file mode 100644 index b412c4d1f0..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configmap-dashboard-provider.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if and .Values.sidecar.dashboards.enabled .Values.sidecar.dashboards.SCProvider }} -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} - name: {{ include "grafana.fullname" . }}-config-dashboards - namespace: {{ include "grafana.namespace" . }} -data: - {{- include "grafana.configDashboardProviderData" . | nindent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configmap.yaml deleted file mode 100644 index 0a2edf47e3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/configmap.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.createConfigmap }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- if or .Values.configMapAnnotations .Values.annotations }} - annotations: - {{- with .Values.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.configMapAnnotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- end }} -data: - {{- include "grafana.configData" . | nindent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/dashboards-json-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/dashboards-json-configmap.yaml deleted file mode 100644 index b96ce72026..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/dashboards-json-configmap.yaml +++ /dev/null @@ -1,38 +0,0 @@ -{{- if .Values.dashboards }} -{{ $files := .Files }} -{{- range $provider, $dashboards := .Values.dashboards }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "grafana.fullname" $ }}-dashboards-{{ $provider }} - namespace: {{ include "grafana.namespace" $ }} - labels: - {{- include "grafana.labels" $ | nindent 4 }} - dashboard-provider: {{ $provider }} - {{- if $.Values.sidecar.dashboards.enabled }} - {{ $.Values.sidecar.dashboards.label }}: {{ $.Values.sidecar.dashboards.labelValue | quote }} - {{- end }} -{{- if $dashboards }} -data: -{{- $dashboardFound := false }} -{{- range $key, $value := $dashboards }} -{{- if (or (hasKey $value "json") (hasKey $value "file")) }} -{{- $dashboardFound = true }} - {{- print $key | nindent 2 }}.json: - {{- if hasKey $value "json" }} - |- - {{- $value.json | nindent 6 }} - {{- end }} - {{- if hasKey $value "file" }} - {{- toYaml ( $files.Get $value.file ) | nindent 4}} - {{- end }} -{{- end }} -{{- end }} -{{- if not $dashboardFound }} - {} -{{- end }} -{{- end }} ---- -{{- end }} - -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/deployment.yaml deleted file mode 100644 index 46c016faa3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/deployment.yaml +++ /dev/null @@ -1,53 +0,0 @@ -{{- if (and (not .Values.useStatefulSet) (or (not .Values.persistence.enabled) (eq .Values.persistence.type "pvc"))) }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- if and (not .Values.autoscaling.enabled) (.Values.replicas) }} - replicas: {{ .Values.replicas }} - {{- end }} - revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} - selector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 6 }} - {{- with .Values.deploymentStrategy }} - strategy: - {{- toYaml . | trim | nindent 4 }} - {{- end }} - template: - metadata: - labels: - {{- include "grafana.selectorLabels" . | nindent 8 }} - {{- with .Values.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - annotations: - checksum/config: {{ include "grafana.configData" . | sha256sum }} - {{- if .Values.dashboards }} - checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} - {{- end }} - checksum/sc-dashboard-provider-config: {{ include "grafana.configDashboardProviderData" . | sha256sum }} - {{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - checksum/secret: {{ include "grafana.secretsData" . | sha256sum }} - {{- end }} - {{- if .Values.envRenderSecret }} - checksum/secret-env: {{ tpl (toYaml .Values.envRenderSecret) . | sha256sum }} - {{- end }} - kubectl.kubernetes.io/default-container: {{ .Chart.Name }} - {{- with .Values.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - {{- include "grafana.pod" . | nindent 6 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/extra-manifests.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/extra-manifests.yaml deleted file mode 100644 index a9bb3b6ba8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/extra-manifests.yaml +++ /dev/null @@ -1,4 +0,0 @@ -{{ range .Values.extraObjects }} ---- -{{ tpl (toYaml .) $ }} -{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/headless-service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/headless-service.yaml deleted file mode 100644 index 3028589d32..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/headless-service.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- $sts := list "sts" "StatefulSet" "statefulset" -}} -{{- if or .Values.headlessService (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (has .Values.persistence.type $sts)) }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "grafana.fullname" . }}-headless - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - clusterIP: None - selector: - {{- include "grafana.selectorLabels" . | nindent 4 }} - type: ClusterIP - ports: - - name: {{ .Values.gossipPortName }}-tcp - port: 9094 -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/hpa.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/hpa.yaml deleted file mode 100644 index 46bbcb49a2..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/hpa.yaml +++ /dev/null @@ -1,52 +0,0 @@ -{{- $sts := list "sts" "StatefulSet" "statefulset" -}} -{{- if .Values.autoscaling.enabled }} -apiVersion: {{ include "grafana.hpa.apiVersion" . }} -kind: HorizontalPodAutoscaler -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - app.kubernetes.io/name: {{ include "grafana.name" . }} - helm.sh/chart: {{ include "grafana.chart" . }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - {{- if has .Values.persistence.type $sts }} - kind: StatefulSet - {{- else }} - kind: Deployment - {{- end }} - name: {{ include "grafana.fullname" . }} - minReplicas: {{ .Values.autoscaling.minReplicas }} - maxReplicas: {{ .Values.autoscaling.maxReplicas }} - metrics: - {{- if .Values.autoscaling.targetMemory }} - - type: Resource - resource: - name: memory - {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} - targetAverageUtilization: {{ .Values.autoscaling.targetMemory }} - {{- else }} - target: - type: Utilization - averageUtilization: {{ .Values.autoscaling.targetMemory }} - {{- end }} - {{- end }} - {{- if .Values.autoscaling.targetCPU }} - - type: Resource - resource: - name: cpu - {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} - targetAverageUtilization: {{ .Values.autoscaling.targetCPU }} - {{- else }} - target: - type: Utilization - averageUtilization: {{ .Values.autoscaling.targetCPU }} - {{- end }} - {{- end }} - {{- if .Values.autoscaling.behavior }} - behavior: {{ toYaml .Values.autoscaling.behavior | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-deployment.yaml deleted file mode 100644 index acf03e4da4..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-deployment.yaml +++ /dev/null @@ -1,199 +0,0 @@ -{{ if .Values.imageRenderer.enabled }} -{{- $root := . -}} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "grafana.fullname" . }}-image-renderer - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.imageRenderer.labels" . | nindent 4 }} - {{- with .Values.imageRenderer.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.imageRenderer.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- if and (not .Values.imageRenderer.autoscaling.enabled) (.Values.imageRenderer.replicas) }} - replicas: {{ .Values.imageRenderer.replicas }} - {{- end }} - revisionHistoryLimit: {{ .Values.imageRenderer.revisionHistoryLimit }} - selector: - matchLabels: - {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} - - {{- with .Values.imageRenderer.deploymentStrategy }} - strategy: - {{- toYaml . | trim | nindent 4 }} - {{- end }} - template: - metadata: - labels: - {{- include "grafana.imageRenderer.selectorLabels" . | nindent 8 }} - {{- with .Values.imageRenderer.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - annotations: - checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} - {{- with .Values.imageRenderer.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - {{- with .Values.imageRenderer.schedulerName }} - schedulerName: "{{ . }}" - {{- end }} - {{- with .Values.imageRenderer.serviceAccountName }} - serviceAccountName: "{{ . }}" - {{- end }} - {{- with .Values.imageRenderer.securityContext }} - securityContext: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.imageRenderer.hostAliases }} - hostAliases: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.imageRenderer.priorityClassName }} - priorityClassName: {{ . }} - {{- end }} - {{- with .Values.imageRenderer.image.pullSecrets }} - imagePullSecrets: - {{- range . }} - - name: {{ tpl . $root }} - {{- end}} - {{- end }} - containers: - - name: {{ .Chart.Name }}-image-renderer - {{- $registry := include "system_default_registry" | default .Values.imageRenderer.image.registry -}} - {{- if .Values.imageRenderer.image.sha }} - image: "{{ $registry }}{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}@sha256:{{ .Values.imageRenderer.image.sha }}" - {{- else }} - image: "{{ $registry }}{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.imageRenderer.image.pullPolicy }} - {{- if .Values.imageRenderer.command }} - command: - {{- range .Values.imageRenderer.command }} - - {{ . }} - {{- end }} - {{- end}} - ports: - - name: {{ .Values.imageRenderer.service.portName }} - containerPort: {{ .Values.imageRenderer.service.targetPort }} - protocol: TCP - livenessProbe: - httpGet: - path: / - port: {{ .Values.imageRenderer.service.portName }} - env: - - name: HTTP_PORT - value: {{ .Values.imageRenderer.service.targetPort | quote }} - {{- if .Values.imageRenderer.serviceMonitor.enabled }} - - name: ENABLE_METRICS - value: "true" - {{- end }} - {{- range $key, $value := .Values.imageRenderer.envValueFrom }} - - name: {{ $key | quote }} - valueFrom: - {{- tpl (toYaml $value) $ | nindent 16 }} - {{- end }} - {{- range $key, $value := .Values.imageRenderer.env }} - - name: {{ $key | quote }} - value: {{ $value | quote }} - {{- end }} - {{- with .Values.imageRenderer.containerSecurityContext }} - securityContext: - {{- toYaml . | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /tmp - name: image-renderer-tmpfs - {{- range .Values.imageRenderer.extraConfigmapMounts }} - - name: {{ tpl .name $root }} - mountPath: {{ tpl .mountPath $root }} - subPath: {{ tpl (.subPath | default "") $root }} - readOnly: {{ .readOnly }} - {{- end }} - {{- range .Values.imageRenderer.extraSecretMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - readOnly: {{ .readOnly }} - subPath: {{ .subPath | default "" }} - {{- end }} - {{- range .Values.imageRenderer.extraVolumeMounts }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - subPath: {{ .subPath | default "" }} - readOnly: {{ .readOnly }} - {{- end }} - {{- with .Values.imageRenderer.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.imageRenderer.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.imageRenderer.affinity }} - affinity: - {{- tpl (toYaml .) $root | nindent 8 }} - {{- end }} - {{- with .Values.imageRenderer.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - volumes: - - name: image-renderer-tmpfs - emptyDir: {} - {{- range .Values.imageRenderer.extraConfigmapMounts }} - - name: {{ tpl .name $root }} - configMap: - name: {{ tpl .configMap $root }} - {{- with .items }} - items: - {{- toYaml . | nindent 14 }} - {{- end }} - {{- end }} - {{- range .Values.imageRenderer.extraSecretMounts }} - {{- if .secretName }} - - name: {{ .name }} - secret: - secretName: {{ .secretName }} - defaultMode: {{ .defaultMode }} - {{- with .items }} - items: - {{- toYaml . | nindent 14 }} - {{- end }} - {{- else if .projected }} - - name: {{ .name }} - projected: - {{- toYaml .projected | nindent 12 }} - {{- else if .csi }} - - name: {{ .name }} - csi: - {{- toYaml .csi | nindent 12 }} - {{- end }} - {{- end }} - {{- range .Values.imageRenderer.extraVolumes }} - - name: {{ .name }} - {{- if .existingClaim }} - persistentVolumeClaim: - claimName: {{ .existingClaim }} - {{- else if .hostPath }} - hostPath: - {{ toYaml .hostPath | nindent 12 }} - {{- else if .csi }} - csi: - {{- toYaml .csi | nindent 12 }} - {{- else if .configMap }} - configMap: - {{- toYaml .configMap | nindent 12 }} - {{- else if .emptyDir }} - emptyDir: - {{- toYaml .emptyDir | nindent 12 }} - {{- else }} - emptyDir: {} - {{- end }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-hpa.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-hpa.yaml deleted file mode 100644 index b0f0059b79..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-hpa.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.autoscaling.enabled }} -apiVersion: {{ include "grafana.hpa.apiVersion" . }} -kind: HorizontalPodAutoscaler -metadata: - name: {{ include "grafana.fullname" . }}-image-renderer - namespace: {{ include "grafana.namespace" . }} - labels: - app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer - helm.sh/chart: {{ include "grafana.chart" . }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: {{ include "grafana.fullname" . }}-image-renderer - minReplicas: {{ .Values.imageRenderer.autoscaling.minReplicas }} - maxReplicas: {{ .Values.imageRenderer.autoscaling.maxReplicas }} - metrics: - {{- if .Values.imageRenderer.autoscaling.targetMemory }} - - type: Resource - resource: - name: memory - {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} - targetAverageUtilization: {{ .Values.imageRenderer.autoscaling.targetMemory }} - {{- else }} - target: - type: Utilization - averageUtilization: {{ .Values.imageRenderer.autoscaling.targetMemory }} - {{- end }} - {{- end }} - {{- if .Values.imageRenderer.autoscaling.targetCPU }} - - type: Resource - resource: - name: cpu - {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} - targetAverageUtilization: {{ .Values.imageRenderer.autoscaling.targetCPU }} - {{- else }} - target: - type: Utilization - averageUtilization: {{ .Values.imageRenderer.autoscaling.targetCPU }} - {{- end }} - {{- end }} - {{- if .Values.imageRenderer.autoscaling.behavior }} - behavior: {{ toYaml .Values.imageRenderer.autoscaling.behavior | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-network-policy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-network-policy.yaml deleted file mode 100644 index bcbd24976c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-network-policy.yaml +++ /dev/null @@ -1,79 +0,0 @@ -{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.networkPolicy.limitIngress }} ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ include "grafana.fullname" . }}-image-renderer-ingress - namespace: {{ include "grafana.namespace" . }} - annotations: - comment: Limit image-renderer ingress traffic from grafana -spec: - podSelector: - matchLabels: - {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} - {{- with .Values.imageRenderer.podLabels }} - {{- toYaml . | nindent 6 }} - {{- end }} - - policyTypes: - - Ingress - ingress: - - ports: - - port: {{ .Values.imageRenderer.service.targetPort }} - protocol: TCP - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: {{ include "grafana.namespace" . }} - podSelector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 14 }} - {{- with .Values.podLabels }} - {{- toYaml . | nindent 14 }} - {{- end }} - {{- with .Values.imageRenderer.networkPolicy.extraIngressSelectors -}} - {{ toYaml . | nindent 8 }} - {{- end }} -{{- end }} - -{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.networkPolicy.limitEgress }} ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ include "grafana.fullname" . }}-image-renderer-egress - namespace: {{ include "grafana.namespace" . }} - annotations: - comment: Limit image-renderer egress traffic to grafana -spec: - podSelector: - matchLabels: - {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} - {{- with .Values.imageRenderer.podLabels }} - {{- toYaml . | nindent 6 }} - {{- end }} - - policyTypes: - - Egress - egress: - # allow dns resolution - - ports: - - port: 53 - protocol: UDP - - port: 53 - protocol: TCP - # talk only to grafana - - ports: - - port: {{ .Values.service.targetPort }} - protocol: TCP - to: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: {{ include "grafana.namespace" . }} - podSelector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 14 }} - {{- with .Values.podLabels }} - {{- toYaml . | nindent 14 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-service.yaml deleted file mode 100644 index f8da127cf8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-service.yaml +++ /dev/null @@ -1,31 +0,0 @@ -{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.service.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "grafana.fullname" . }}-image-renderer - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.imageRenderer.labels" . | nindent 4 }} - {{- with .Values.imageRenderer.service.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.imageRenderer.service.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - {{- with .Values.imageRenderer.service.clusterIP }} - clusterIP: {{ . }} - {{- end }} - ports: - - name: {{ .Values.imageRenderer.service.portName }} - port: {{ .Values.imageRenderer.service.port }} - protocol: TCP - targetPort: {{ .Values.imageRenderer.service.targetPort }} - {{- with .Values.imageRenderer.appProtocol }} - appProtocol: {{ . }} - {{- end }} - selector: - {{- include "grafana.imageRenderer.selectorLabels" . | nindent 4 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-servicemonitor.yaml deleted file mode 100644 index 5d9f09d266..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/image-renderer-servicemonitor.yaml +++ /dev/null @@ -1,48 +0,0 @@ -{{- if .Values.imageRenderer.serviceMonitor.enabled }} ---- -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ include "grafana.fullname" . }}-image-renderer - {{- if .Values.imageRenderer.serviceMonitor.namespace }} - namespace: {{ tpl .Values.imageRenderer.serviceMonitor.namespace . }} - {{- else }} - namespace: {{ include "grafana.namespace" . }} - {{- end }} - labels: - {{- include "grafana.imageRenderer.labels" . | nindent 4 }} - {{- with .Values.imageRenderer.serviceMonitor.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - endpoints: - - port: {{ .Values.imageRenderer.service.portName }} - {{- with .Values.imageRenderer.serviceMonitor.interval }} - interval: {{ . }} - {{- end }} - {{- with .Values.imageRenderer.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ . }} - {{- end }} - honorLabels: true - path: {{ .Values.imageRenderer.serviceMonitor.path }} - scheme: {{ .Values.imageRenderer.serviceMonitor.scheme }} - {{- with .Values.imageRenderer.serviceMonitor.tlsConfig }} - tlsConfig: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.imageRenderer.serviceMonitor.relabelings }} - relabelings: - {{- toYaml . | nindent 6 }} - {{- end }} - jobLabel: "{{ .Release.Name }}-image-renderer" - selector: - matchLabels: - {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} - namespaceSelector: - matchNames: - - {{ include "grafana.namespace" . }} - {{- with .Values.imageRenderer.serviceMonitor.targetLabels }} - targetLabels: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/ingress.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/ingress.yaml deleted file mode 100644 index b2ffd81095..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/ingress.yaml +++ /dev/null @@ -1,78 +0,0 @@ -{{- if .Values.ingress.enabled -}} -{{- $ingressApiIsStable := eq (include "grafana.ingress.isStable" .) "true" -}} -{{- $ingressSupportsIngressClassName := eq (include "grafana.ingress.supportsIngressClassName" .) "true" -}} -{{- $ingressSupportsPathType := eq (include "grafana.ingress.supportsPathType" .) "true" -}} -{{- $fullName := include "grafana.fullname" . -}} -{{- $servicePort := .Values.service.port -}} -{{- $ingressPath := .Values.ingress.path -}} -{{- $ingressPathType := .Values.ingress.pathType -}} -{{- $extraPaths := .Values.ingress.extraPaths -}} -apiVersion: {{ include "grafana.ingress.apiVersion" . }} -kind: Ingress -metadata: - name: {{ $fullName }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- 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 . $ | quote }} - 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/networkpolicy.yaml deleted file mode 100644 index 4cd3ed6976..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/networkpolicy.yaml +++ /dev/null @@ -1,61 +0,0 @@ -{{- if .Values.networkPolicy.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - policyTypes: - {{- if .Values.networkPolicy.ingress }} - - Ingress - {{- end }} - {{- if .Values.networkPolicy.egress.enabled }} - - Egress - {{- end }} - podSelector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 6 }} - - {{- if .Values.networkPolicy.egress.enabled }} - egress: - {{- if not .Values.networkPolicy.egress.blockDNSResolution }} - - ports: - - port: 53 - protocol: UDP - {{- end }} - - ports: - {{ .Values.networkPolicy.egress.ports | toJson }} - {{- with .Values.networkPolicy.egress.to }} - to: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- end }} - {{- if .Values.networkPolicy.ingress }} - ingress: - - ports: - - port: {{ .Values.service.targetPort }} - {{- if not .Values.networkPolicy.allowExternal }} - from: - - podSelector: - matchLabels: - {{ include "grafana.fullname" . }}-client: "true" - {{- with .Values.networkPolicy.explicitNamespacesSelector }} - - namespaceSelector: - {{- toYaml . | nindent 12 }} - {{- end }} - - podSelector: - matchLabels: - {{- include "grafana.labels" . | nindent 14 }} - role: read - {{- end }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/nginx-config.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/nginx-config.yaml deleted file mode 100644 index 557471f6ff..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/nginx-config.yaml +++ /dev/null @@ -1,94 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-nginx-proxy-config - namespace: {{ template "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -data: - nginx.conf: |- - worker_processes auto; - error_log /dev/stdout warn; - pid /var/cache/nginx/nginx.pid; - - events { - worker_connections 1024; - } - - http { - include /etc/nginx/mime.types; - log_format main '[$time_local - $status] $remote_addr - $remote_user $request ($http_referer)'; - - proxy_connect_timeout 10; - proxy_read_timeout 180; - proxy_send_timeout 5; - proxy_buffering off; - proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my_zone:100m inactive=1d max_size=10g; - - map $http_upgrade $connection_upgrade { - default upgrade; - '' close; - } - - server { - listen 8080; - access_log off; - - gzip on; - gzip_min_length 1k; - gzip_comp_level 2; - gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript image/jpeg image/gif image/png; - gzip_vary on; - gzip_disable "MSIE [1-6]\."; - - proxy_set_header Host $host; - - location /api/dashboards { - proxy_pass http://localhost:3000; - } - - location /api/search { - proxy_pass http://localhost:3000; - - sub_filter_types application/json; - sub_filter_once off; - } - - location /api/live/ { - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_set_header Host $http_host; - proxy_pass http://localhost:3000; - } - - location / { - proxy_cache my_zone; - proxy_cache_valid 200 302 1d; - proxy_cache_valid 301 30d; - proxy_cache_valid any 5m; - proxy_cache_bypass $http_cache_control; - add_header X-Proxy-Cache $upstream_cache_status; - add_header Cache-Control "public"; - - proxy_pass http://localhost:3000/; - - sub_filter_once off; - - {{- if eq .Values.global.cattle.clusterId "local" -}} - sub_filter '"appSubUrl":""' '"appSubUrl":"/api/v1/namespaces/{{ template "grafana.namespace" . }}/services/http:{{ template "grafana.fullname" . }}:{{ .Values.service.port }}/proxy"'; - {{- else -}} - sub_filter '"appSubUrl":""' '"appSubUrl":"/k8s/clusters/{{ .Values.global.cattle.clusterId }}/api/v1/namespaces/{{ template "grafana.namespace" . }}/services/http:{{ template "grafana.fullname" . }}:{{ .Values.service.port }}/proxy"'; - {{- end -}} - - sub_filter ':"/avatar/' ':"avatar/'; - - if ($request_filename ~ .*\.(?:js|css|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$) { - expires 90d; - } - - rewrite ^/k8s/clusters/.*/proxy(.*) /$1 break; - - } - } - } diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/poddisruptionbudget.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/poddisruptionbudget.yaml deleted file mode 100644 index 05251214ac..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/poddisruptionbudget.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- if .Values.podDisruptionBudget }} -apiVersion: {{ include "grafana.podDisruptionBudget.apiVersion" . }} -kind: PodDisruptionBudget -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- with .Values.podDisruptionBudget.minAvailable }} - minAvailable: {{ . }} - {{- end }} - {{- with .Values.podDisruptionBudget.maxUnavailable }} - maxUnavailable: {{ . }} - {{- end }} - selector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 6 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/podsecuritypolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/podsecuritypolicy.yaml deleted file mode 100644 index ebbdef5b5e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/podsecuritypolicy.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- if and .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ include "grafana.fullname" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -{{- if .Values.rbac.pspAnnotations }} - annotations: {{ toYaml .Values.rbac.pspAnnotations | nindent 4 }} -{{- end }} -spec: - privileged: false - allowPrivilegeEscalation: false - requiredDropCapabilities: - # Default set from Docker, with DAC_OVERRIDE and CHOWN - - ALL - volumes: - - 'configMap' - - 'emptyDir' - - 'projected' - - 'csi' - - 'secret' - - 'downwardAPI' - - 'persistentVolumeClaim' - hostNetwork: false - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - # Forbid adding the root group. - - min: 1 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - # Forbid adding the root group. - - min: 1 - max: 65535 - readOnlyRootFilesystem: false -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/pvc.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/pvc.yaml deleted file mode 100644 index b5fd5d4a3b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/pvc.yaml +++ /dev/null @@ -1,41 +0,0 @@ -{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "pvc")}} -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.persistence.extraPvcLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.persistence.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.persistence.finalizers }} - finalizers: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - accessModes: -{{- $_ := required "Must provide at least one access mode for persistent volumes used by Grafana" .Values.persistence.accessModes }} -{{- $_ := required "Must provide at least one access mode for persistent volumes used by Grafana" (first .Values.persistence.accessModes) }} - {{- range .Values.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} - {{- if and (.Values.persistence.lookupVolumeName) (lookup "v1" "PersistentVolumeClaim" (include "grafana.namespace" .) (include "grafana.fullname" .)) }} - volumeName: {{ (lookup "v1" "PersistentVolumeClaim" (include "grafana.namespace" .) (include "grafana.fullname" .)).spec.volumeName }} - {{- end }} - {{- with .Values.persistence.storageClassName }} - storageClassName: {{ . }} - {{- end }} - {{- with .Values.persistence.selectorLabels }} - selector: - matchLabels: - {{- toYaml . | nindent 6 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/role.yaml deleted file mode 100644 index 4b5edd978c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/role.yaml +++ /dev/null @@ -1,32 +0,0 @@ -{{- if and .Values.rbac.create (not .Values.rbac.useExistingRole) -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- if or .Values.rbac.pspEnabled (and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled .Values.rbac.extraRoleRules)) }} -rules: - {{- if and .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} - - apiGroups: ['extensions'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: [{{ include "grafana.fullname" . }}] - {{- end }} - {{- if and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled) }} - - apiGroups: [""] # "" indicates the core API group - resources: ["configmaps", "secrets"] - verbs: ["get", "watch", "list"] - {{- end }} - {{- with .Values.rbac.extraRoleRules }} - {{- toYaml . | nindent 2 }} - {{- end}} -{{- else }} -rules: [] -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/rolebinding.yaml deleted file mode 100644 index 58f77c6b0b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/rolebinding.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- if .Values.rbac.create }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - {{- if .Values.rbac.useExistingRole }} - name: {{ .Values.rbac.useExistingRole }} - {{- else }} - name: {{ include "grafana.fullname" . }} - {{- end }} -subjects: -- kind: ServiceAccount - name: {{ include "grafana.serviceAccountName" . }} - namespace: {{ include "grafana.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/secret-env.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/secret-env.yaml deleted file mode 100644 index eb14aac707..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/secret-env.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if .Values.envRenderSecret }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "grafana.fullname" . }}-env - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} -type: Opaque -data: -{{- range $key, $val := .Values.envRenderSecret }} - {{ $key }}: {{ tpl ($val | toString) $ | b64enc | quote }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/secret.yaml deleted file mode 100644 index fd2ca50f4b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/secret.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret)) }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -type: Opaque -data: - {{- include "grafana.secretsData" . | nindent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/service.yaml deleted file mode 100644 index 022328c114..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/service.yaml +++ /dev/null @@ -1,67 +0,0 @@ -{{- if .Values.service.enabled }} -{{- $root := . }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.service.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.service.annotations }} - annotations: - {{- tpl (toYaml . | nindent 4) $root }} - {{- end }} -spec: - {{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} - type: ClusterIP - {{- with .Values.service.clusterIP }} - clusterIP: {{ . }} - {{- end }} - {{- else if eq .Values.service.type "LoadBalancer" }} - type: LoadBalancer - {{- with .Values.service.loadBalancerIP }} - loadBalancerIP: {{ . }} - {{- end }} - {{- with .Values.service.loadBalancerClass }} - loadBalancerClass: {{ . }} - {{- end }} - {{- with .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- else }} - type: {{ .Values.service.type }} - {{- end }} - {{- if .Values.service.ipFamilyPolicy }} - ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} - {{- end }} - {{- if .Values.service.ipFamilies }} - ipFamilies: {{ .Values.service.ipFamilies | toYaml | nindent 2 }} - {{- end }} - {{- with .Values.service.externalIPs }} - externalIPs: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.service.externalTrafficPolicy }} - externalTrafficPolicy: {{ . }} - {{- end }} - ports: - - name: {{ .Values.service.portName }} - port: {{ .Values.service.port }} - protocol: TCP - targetPort: {{ .Values.service.targetPort }} - {{- with .Values.service.appProtocol }} - appProtocol: {{ . }} - {{- end }} - {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} - {{- with .Values.extraExposePorts }} - {{- tpl (toYaml . | nindent 4) $root }} - {{- end }} - selector: - {{- include "grafana.selectorLabels" . | nindent 4 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/serviceaccount.yaml deleted file mode 100644 index ffca0717ae..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/serviceaccount.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.serviceAccount.create }} -apiVersion: v1 -kind: ServiceAccount -automountServiceAccountToken: {{ .Values.serviceAccount.autoMount | default .Values.serviceAccount.automountServiceAccountToken }} -metadata: - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- tpl (toYaml . | nindent 4) $ }} - {{- end }} - name: {{ include "grafana.serviceAccountName" . }} - namespace: {{ include "grafana.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/servicemonitor.yaml deleted file mode 100644 index 160a9c5562..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/servicemonitor.yaml +++ /dev/null @@ -1,66 +0,0 @@ -{{- if .Values.serviceMonitor.enabled }} ---- -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ include "grafana.fullname" . }} - {{- if .Values.serviceMonitor.namespace }} - namespace: {{ tpl .Values.serviceMonitor.namespace . }} - {{- else }} - namespace: {{ include "grafana.namespace" . }} - {{- end }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.serviceMonitor.labels }} - {{- tpl (toYaml . | nindent 4) $ }} - {{- end }} -spec: - endpoints: - - port: {{ .Values.service.portName }} - {{- with .Values.serviceMonitor.interval }} - interval: {{ . }} - {{- end }} - {{- with .Values.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ . }} - {{- end }} - honorLabels: true - path: {{ .Values.serviceMonitor.path }} - scheme: {{ .Values.serviceMonitor.scheme }} - {{- with .Values.serviceMonitor.tlsConfig }} - tlsConfig: - {{- toYaml . | nindent 6 }} - {{- end }} - metricRelabelings: - {{- if .Values.serviceMonitor.metricRelabelings }} - {{- toYaml .Values.serviceMonitor.metricRelabelings | nindent 6 }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName }} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} - {{- with .Values.serviceMonitor.relabelings }} - relabelings: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.serviceMonitor.metricRelabelings }} - metricRelabelings: - {{- toYaml . | nindent 6 }} - {{- end }} - jobLabel: "{{ .Release.Name }}" - selector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 6 }} - namespaceSelector: - matchNames: - - {{ include "grafana.namespace" . }} - {{- with .Values.serviceMonitor.targetLabels }} - targetLabels: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/statefulset.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/statefulset.yaml deleted file mode 100644 index 49278083e8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/statefulset.yaml +++ /dev/null @@ -1,58 +0,0 @@ -{{- $sts := list "sts" "StatefulSet" "statefulset" -}} -{{- if (or (.Values.useStatefulSet) (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (has .Values.persistence.type $sts)))}} -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ include "grafana.fullname" . }} - namespace: {{ include "grafana.namespace" . }} - labels: - {{- include "grafana.labels" . | nindent 4 }} - {{- with .Values.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - replicas: {{ .Values.replicas }} - selector: - matchLabels: - {{- include "grafana.selectorLabels" . | nindent 6 }} - serviceName: {{ include "grafana.fullname" . }}-headless - template: - metadata: - labels: - {{- include "grafana.selectorLabels" . | nindent 8 }} - {{- with .Values.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - annotations: - checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} - checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} - checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }} - {{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} - checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} - {{- end }} - kubectl.kubernetes.io/default-container: {{ .Chart.Name }} - {{- with .Values.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - {{- include "grafana.pod" . | nindent 6 }} - {{- if .Values.persistence.enabled}} - volumeClaimTemplates: - - metadata: - name: storage - spec: -{{- $_ := required "Must provide at least one access mode for persistent volumes used by Grafana" .Values.persistence.accessModes }} -{{- $_ := required "Must provide at least one access mode for persistent volumes used by Grafana" (first .Values.persistence.accessModes) }} - accessModes: {{ .Values.persistence.accessModes }} - storageClassName: {{ .Values.persistence.storageClassName }} - resources: - requests: - storage: {{ required "Must provide size for persistent volumes used by Grafana" .Values.persistence.size }} - {{- with .Values.persistence.selectorLabels }} - selector: - matchLabels: - {{- toYaml . | nindent 10 }} - {{- end }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-configmap.yaml deleted file mode 100644 index 01c96c9243..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-configmap.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.testFramework.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "grafana.fullname" . }}-test - namespace: {{ include "grafana.namespace" . }} - annotations: - "helm.sh/hook": test-success - "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" - labels: - {{- include "grafana.labels" . | nindent 4 }} -data: - run.sh: |- - @test "Test Health" { - url="http://{{ include "grafana.fullname" . }}/api/health" - - code=$(wget --server-response --spider --timeout 90 --tries 10 ${url} 2>&1 | awk '/^ HTTP/{print $2}') - [ "$code" == "200" ] - } -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-podsecuritypolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-podsecuritypolicy.yaml deleted file mode 100644 index 1821772a45..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-podsecuritypolicy.yaml +++ /dev/null @@ -1,32 +0,0 @@ -{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ include "grafana.fullname" . }}-test - annotations: - "helm.sh/hook": test-success - "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" - labels: - {{- include "grafana.labels" . | nindent 4 }} -spec: - allowPrivilegeEscalation: true - privileged: false - hostNetwork: false - hostIPC: false - hostPID: false - fsGroup: - rule: RunAsAny - seLinux: - rule: RunAsAny - supplementalGroups: - rule: RunAsAny - runAsUser: - rule: RunAsAny - volumes: - - configMap - - downwardAPI - - emptyDir - - projected - - csi - - secret -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-role.yaml deleted file mode 100644 index cb4c782040..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-role.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ include "grafana.fullname" . }}-test - namespace: {{ include "grafana.namespace" . }} - annotations: - "helm.sh/hook": test-success - "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" - labels: - {{- include "grafana.labels" . | nindent 4 }} -rules: - - apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: [{{ include "grafana.fullname" . }}-test] -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-rolebinding.yaml deleted file mode 100644 index f40d791f6c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-rolebinding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ include "grafana.fullname" . }}-test - namespace: {{ include "grafana.namespace" . }} - annotations: - "helm.sh/hook": test-success - "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" - labels: - {{- include "grafana.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ include "grafana.fullname" . }}-test -subjects: - - kind: ServiceAccount - name: {{ include "grafana.serviceAccountNameTest" . }} - namespace: {{ include "grafana.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-serviceaccount.yaml deleted file mode 100644 index 38fba3596a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test-serviceaccount.yaml +++ /dev/null @@ -1,12 +0,0 @@ -{{- if and .Values.testFramework.enabled .Values.serviceAccount.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "grafana.labels" . | nindent 4 }} - name: {{ include "grafana.serviceAccountNameTest" . }} - namespace: {{ include "grafana.namespace" . }} - annotations: - "helm.sh/hook": test-success - "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test.yaml deleted file mode 100644 index 83aaa185c2..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/templates/tests/test.yaml +++ /dev/null @@ -1,53 +0,0 @@ -{{- if .Values.testFramework.enabled }} -{{- $root := . }} -apiVersion: v1 -kind: Pod -metadata: - name: {{ include "grafana.fullname" . }}-test - labels: - {{- include "grafana.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": test-success - "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" - namespace: {{ include "grafana.namespace" . }} -spec: - serviceAccountName: {{ include "grafana.serviceAccountNameTest" . }} - {{- with .Values.testFramework.securityContext }} - securityContext: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- if or .Values.image.pullSecrets .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- include "grafana.imagePullSecrets" (dict "root" $root "imagePullSecrets" .Values.image.pullSecrets) | nindent 4 }} - {{- end }} - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.affinity }} - affinity: - {{- tpl (toYaml .) $root | nindent 4 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 4 }} - {{- end }} - containers: - - name: {{ .Release.Name }}-test - image: "{{ template "system_default_registry" . | default .Values.testFramework.image.registry }}/{{ .Values.testFramework.image.repository }}:{{ .Values.testFramework.image.tag }}" - imagePullPolicy: "{{ .Values.testFramework.imagePullPolicy}}" - command: ["/opt/bats/bin/bats", "-t", "/tests/run.sh"] - volumeMounts: - - mountPath: /tests - name: tests - readOnly: true - {{- with .Values.testFramework.resources }} - resources: - {{- toYaml . | nindent 8 }} - {{- end }} - volumes: - - name: tests - configMap: - name: {{ include "grafana.fullname" . }}-test - restartPolicy: Never -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/values.yaml deleted file mode 100644 index c338ae041e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/grafana/values.yaml +++ /dev/null @@ -1,1365 +0,0 @@ -global: - cattle: - systemDefaultRegistry: "" - - # To help compatibility with other charts which use global.imagePullSecrets. - # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). - # Can be templated. - # global: - # imagePullSecrets: - # - name: pullSecret1 - # - name: pullSecret2 - # or - # global: - # imagePullSecrets: - # - pullSecret1 - # - pullSecret2 - imagePullSecrets: [] - -rbac: - create: true - ## Use an existing ClusterRole/Role (depending on rbac.namespaced false/true) - # useExistingRole: name-of-some-role - # useExistingClusterRole: name-of-some-clusterRole - pspEnabled: false - pspUseAppArmor: false - namespaced: false - extraRoleRules: [] - # - apiGroups: [] - # resources: [] - # verbs: [] - extraClusterRoleRules: [] - # - apiGroups: [] - # resources: [] - # verbs: [] -serviceAccount: - create: true - name: - nameTest: - ## ServiceAccount labels. - labels: {} - ## Service account annotations. Can be templated. - # annotations: - # eks.amazonaws.com/role-arn: arn:aws:iam::123456789000:role/iam-role-name-here - - ## autoMount is deprecated in favor of automountServiceAccountToken - # autoMount: false - automountServiceAccountToken: true - -replicas: 1 - -## Create a headless service for the deployment -headlessService: false - -## Should the service account be auto mounted on the pod -automountServiceAccountToken: true - -## Create HorizontalPodAutoscaler object for deployment type -# -autoscaling: - enabled: false - minReplicas: 1 - maxReplicas: 5 - targetCPU: "60" - targetMemory: "" - behavior: {} - -## See `kubectl explain poddisruptionbudget.spec` for more -## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ -podDisruptionBudget: {} -# apiVersion: "" -# minAvailable: 1 -# maxUnavailable: 1 - -## See `kubectl explain deployment.spec.strategy` for more -## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy -deploymentStrategy: - type: RollingUpdate - -readinessProbe: - httpGet: - path: /api/health - port: 3000 - -livenessProbe: - httpGet: - path: /api/health - port: 3000 - initialDelaySeconds: 60 - timeoutSeconds: 30 - failureThreshold: 10 - -## Use an alternate scheduler, e.g. "stork". -## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ -## -# schedulerName: "default-scheduler" - -image: - repository: rancher/mirrored-grafana-grafana - # Overrides the Grafana image tag whose default is the chart appVersion - tag: 11.1.0 - sha: "" - pullPolicy: IfNotPresent - - ## 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/ - ## Can be templated. - ## - pullSecrets: [] - # - myRegistrKeySecretName - -testFramework: - enabled: false - imagePullPolicy: IfNotPresent - securityContext: - runAsNonRoot: true - runAsUser: 1000 - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - -# dns configuration for pod -dnsPolicy: ~ -dnsConfig: {} - # nameservers: - # - 8.8.8.8 - # options: - # - name: ndots - # value: "2" - # - name: edns0 - -securityContext: - runAsNonRoot: true - runAsUser: 472 - runAsGroup: 472 - fsGroup: 472 - -containerSecurityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - seccompProfile: - type: RuntimeDefault - -# Enable creating the grafana configmap -createConfigmap: true - -# Extra configmaps to mount in grafana pods -# Values are templated. -extraConfigmapMounts: [] - # - name: certs-configmap - # mountPath: /etc/grafana/ssl/ - # subPath: certificates.crt # (optional) - # configMap: certs-configmap - # readOnly: true - - -extraEmptyDirMounts: [] - # - name: provisioning-notifiers - # mountPath: /etc/grafana/provisioning/notifiers - - -# Apply extra labels to common labels. -extraLabels: {} - -## Assign a PriorityClassName to pods if set -# priorityClassName: - -downloadDashboardsImage: - repository: rancher/mirrored-curlimages-curl - tag: 8.9.1 - sha: "" - pullPolicy: IfNotPresent - -downloadDashboards: - env: {} - envFromSecret: "" - resources: {} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - seccompProfile: - type: RuntimeDefault - envValueFrom: {} - # ENV_NAME: - # configMapKeyRef: - # name: configmap-name - # key: value_key - -## Pod Annotations -# podAnnotations: {} - -## ConfigMap Annotations -# configMapAnnotations: {} - # argocd.argoproj.io/sync-options: Replace=true - -## Pod Labels -# podLabels: {} - -podPortName: grafana -gossipPortName: gossip -## Deployment annotations -# annotations: {} - -## Expose the grafana 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: - enabled: true - type: ClusterIP - # Set the ip family policy to configure dual-stack see [Configure dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) - ipFamilyPolicy: "" - # Sets the families that should be supported and the order in which they should be applied to ClusterIP as well. Can be IPv4 and/or IPv6. - ipFamilies: [] - loadBalancerIP: "" - loadBalancerClass: "" - loadBalancerSourceRanges: [] - port: 80 - targetPort: 3000 - # targetPort: 4181 To be used with a proxy extraContainer - ## Service annotations. Can be templated. - annotations: {} - labels: {} - portName: service - # Adds the appProtocol field to the service. This allows to work with istio protocol selection. Ex: "http" or "tcp" - appProtocol: "" - -serviceMonitor: - ## If true, a ServiceMonitor CR is created for a prometheus operator - ## https://github.com/coreos/prometheus-operator - ## - enabled: false - path: /metrics - # namespace: monitoring (defaults to use the namespace this chart is deployed to) - labels: {} - interval: 30s - scheme: http - tlsConfig: {} - scrapeTimeout: 30s - relabelings: [] - metricRelabelings: [] - targetLabels: [] - -extraExposePorts: [] - # - name: keycloak - # port: 8080 - # targetPort: 8080 - -# overrides pod.spec.hostAliases in the grafana deployment's pods -hostAliases: [] - # - ip: "1.2.3.4" - # hostnames: - # - "my.host.com" - -ingress: - 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: / - - # 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 - -resources: {} -# limits: -# cpu: 100m -# memory: 128Mi -# requests: -# cpu: 100m -# memory: 128Mi - -## Node labels for pod assignment -## ref: https://kubernetes.io/docs/user-guide/node-selection/ -# -nodeSelector: {} - -## Tolerations for pod assignment -## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ -## -tolerations: [] - -## Affinity for pod assignment (evaluated as template) -## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity -## -affinity: {} - -## Topology Spread Constraints -## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ -## -topologySpreadConstraints: [] - -## Additional init containers (evaluated as template) -## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ -## -extraInitContainers: [] - -## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod -extraContainers: "" -# extraContainers: | -# - name: proxy -# image: quay.io/gambol99/keycloak-proxy:latest -# args: -# - -provider=github -# - -client-id= -# - -client-secret= -# - -github-org= -# - -email-domain=* -# - -cookie-secret= -# - -http-address=http://0.0.0.0:4181 -# - -upstream-url=http://127.0.0.1:3000 -# ports: -# - name: proxy-web -# containerPort: 4181 - -## Volumes that can be used in init containers that will not be mounted to deployment pods -extraContainerVolumes: [] -# - name: volume-from-secret -# secret: -# secretName: secret-to-mount -# - name: empty-dir-volume -# emptyDir: {} - -## Enable persistence using Persistent Volume Claims -## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ -## -persistence: - type: pvc - enabled: false - # storageClassName: default - accessModes: - - ReadWriteOnce - size: 10Gi - # annotations: {} - finalizers: - - kubernetes.io/pvc-protection - # selectorLabels: {} - ## Sub-directory of the PV to mount. Can be templated. - # subPath: "" - ## Name of an existing PVC. Can be templated. - # existingClaim: - ## Extra labels to apply to a PVC. - extraPvcLabels: {} - disableWarning: false - - ## If persistence is not enabled, this allows to mount the - ## local storage in-memory to improve performance - ## - inMemory: - enabled: false - ## The maximum usage on memory medium EmptyDir would be - ## the minimum value between the SizeLimit specified - ## here and the sum of memory limits of all containers in a pod - ## - # sizeLimit: 300Mi - - ## If 'lookupVolumeName' is set to true, Helm will attempt to retrieve - ## the current value of 'spec.volumeName' and incorporate it into the template. - lookupVolumeName: true - -initChownData: - ## If false, data ownership will not be reset at startup - ## This allows the grafana-server to be run with an arbitrary user - ## - enabled: true - - ## initChownData container image - ## - image: - repository: rancher/mirrored-library-busybox - tag: "1.31.1" - sha: "" - pullPolicy: IfNotPresent - - ## initChownData resource requests and limits - ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: {} - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - securityContext: - runAsNonRoot: false - runAsUser: 0 - seccompProfile: - type: RuntimeDefault - capabilities: - add: - - CHOWN - -# Administrator credentials when not using an existing secret (see below) -adminUser: admin -# adminPassword: strongpassword - -# Use an existing secret for the admin user. -admin: - ## Name of the secret. Can be templated. - existingSecret: "" - userKey: admin-user - passwordKey: admin-password - -## Define command to be executed at startup by grafana container -## Needed if using `vault-env` to manage secrets (ref: https://banzaicloud.com/blog/inject-secrets-into-pods-vault/) -## Default is "run.sh" as defined in grafana's Dockerfile -# command: -# - "sh" -# - "/run.sh" - -## Optionally define args if command is used -## Needed if using `hashicorp/envconsul` to manage secrets -## By default no arguments are set -# args: -# - "-secret" -# - "secret/grafana" -# - "./grafana" - -## Extra environment variables that will be pass onto deployment pods -## -## to provide grafana with access to CloudWatch on AWS EKS: -## 1. create an iam role of type "Web identity" with provider oidc.eks.* (note the provider for later) -## 2. edit the "Trust relationships" of the role, add a line inside the StringEquals clause using the -## same oidc eks provider as noted before (same as the existing line) -## also, replace NAMESPACE and prometheus-operator-grafana with the service account namespace and name -## -## "oidc.eks.us-east-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:sub": "system:serviceaccount:NAMESPACE:prometheus-operator-grafana", -## -## 3. attach a policy to the role, you can use a built in policy called CloudWatchReadOnlyAccess -## 4. use the following env: (replace 123456789000 and iam-role-name-here with your aws account number and role name) -## -## env: -## AWS_ROLE_ARN: arn:aws:iam::123456789000:role/iam-role-name-here -## AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token -## AWS_REGION: us-east-1 -## -## 5. uncomment the EKS section in extraSecretMounts: below -## 6. uncomment the annotation section in the serviceAccount: above -## make sure to replace arn:aws:iam::123456789000:role/iam-role-name-here with your role arn - -env: {} - -## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. -## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core -## Renders in container spec as: -## env: -## ... -## - name: -## valueFrom: -## -envValueFrom: {} - # ENV_NAME: - # configMapKeyRef: - # name: configmap-name - # key: value_key - -## The name of a secret in the same kubernetes namespace which contain values to be added to the environment -## This can be useful for auth tokens, etc. Value is templated. -envFromSecret: "" - -## Sensible environment variables that will be rendered as new secret object -## This can be useful for auth tokens, etc. -## If the secret values contains "{{", they'll need to be properly escaped so that they are not interpreted by Helm -## ref: https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function -envRenderSecret: {} - -## The names of secrets in the same kubernetes namespace which contain values to be added to the environment -## Each entry should contain a name key, and can optionally specify whether the secret must be defined with an optional key. -## Name is templated. -envFromSecrets: [] -## - name: secret-name -## prefix: prefix -## optional: true - -## The names of conifgmaps in the same kubernetes namespace which contain values to be added to the environment -## Each entry should contain a name key, and can optionally specify whether the configmap must be defined with an optional key. -## Name is templated. -## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#configmapenvsource-v1-core -envFromConfigMaps: [] -## - name: configmap-name -## prefix: prefix -## optional: true - -# Inject Kubernetes services as environment variables. -# See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#environment-variables -enableServiceLinks: true - -## Additional grafana server secret mounts -# Defines additional mounts with secrets. Secrets must be manually created in the namespace. -extraSecretMounts: [] - # - name: secret-files - # mountPath: /etc/secrets - # secretName: grafana-secret-files - # readOnly: true - # subPath: "" - # - # for AWS EKS (cloudwatch) use the following (see also instruction in env: above) - # - name: aws-iam-token - # mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount - # readOnly: true - # projected: - # defaultMode: 420 - # sources: - # - serviceAccountToken: - # audience: sts.amazonaws.com - # expirationSeconds: 86400 - # path: token - # - # for CSI e.g. Azure Key Vault use the following - # - name: secrets-store-inline - # mountPath: /run/secrets - # readOnly: true - # csi: - # driver: secrets-store.csi.k8s.io - # readOnly: true - # volumeAttributes: - # secretProviderClass: "akv-grafana-spc" - # nodePublishSecretRef: # Only required when using service principal mode - # name: grafana-akv-creds # Only required when using service principal mode - -## Additional grafana server volume mounts -# Defines additional volume mounts. -extraVolumeMounts: [] - # - name: extra-volume-0 - # mountPath: /mnt/volume0 - # readOnly: true - # - name: extra-volume-1 - # mountPath: /mnt/volume1 - # readOnly: true - # - name: grafana-secrets - # mountPath: /mnt/volume2 - -## Additional Grafana server volumes -extraVolumes: [] - # - name: extra-volume-0 - # existingClaim: volume-claim - # - name: extra-volume-1 - # hostPath: - # path: /usr/shared/ - # type: "" - # - name: grafana-secrets - # csi: - # driver: secrets-store.csi.k8s.io - # readOnly: true - # volumeAttributes: - # secretProviderClass: "grafana-env-spc" - -## Container Lifecycle Hooks. Execute a specific bash command or make an HTTP request -lifecycleHooks: {} - # postStart: - # exec: - # command: [] - -## Pass the plugins you want installed as a list. -## -plugins: [] - # - digrich-bubblechart-panel - # - grafana-clock-panel - ## You can also use other plugin download URL, as long as they are valid zip files, - ## and specify the name of the plugin after the semicolon. Like this: - # - https://grafana.com/api/plugins/marcusolsson-json-datasource/versions/1.3.2/download;marcusolsson-json-datasource - -## Configure grafana datasources -## ref: http://docs.grafana.org/administration/provisioning/#datasources -## -datasources: {} -# datasources.yaml: -# apiVersion: 1 -# datasources: -# - name: Prometheus -# type: prometheus -# url: http://prometheus-prometheus-server -# access: proxy -# isDefault: true -# - name: CloudWatch -# type: cloudwatch -# access: proxy -# uid: cloudwatch -# editable: false -# jsonData: -# authType: default -# defaultRegion: us-east-1 -# deleteDatasources: [] -# - name: Prometheus - -## Configure grafana alerting (can be templated) -## ref: http://docs.grafana.org/administration/provisioning/#alerting -## -alerting: {} - # rules.yaml: - # apiVersion: 1 - # groups: - # - orgId: 1 - # name: '{{ .Chart.Name }}_my_rule_group' - # folder: my_first_folder - # interval: 60s - # rules: - # - uid: my_id_1 - # title: my_first_rule - # condition: A - # data: - # - refId: A - # datasourceUid: '-100' - # model: - # conditions: - # - evaluator: - # params: - # - 3 - # type: gt - # operator: - # type: and - # query: - # params: - # - A - # reducer: - # type: last - # type: query - # datasource: - # type: __expr__ - # uid: '-100' - # expression: 1==0 - # intervalMs: 1000 - # maxDataPoints: 43200 - # refId: A - # type: math - # dashboardUid: my_dashboard - # panelId: 123 - # noDataState: Alerting - # for: 60s - # annotations: - # some_key: some_value - # labels: - # team: sre_team_1 - # contactpoints.yaml: - # secret: - # apiVersion: 1 - # contactPoints: - # - orgId: 1 - # name: cp_1 - # receivers: - # - uid: first_uid - # type: pagerduty - # settings: - # integrationKey: XXX - # severity: critical - # class: ping failure - # component: Grafana - # group: app-stack - # summary: | - # {{ `{{ include "default.message" . }}` }} - -## Configure notifiers -## ref: http://docs.grafana.org/administration/provisioning/#alert-notification-channels -## -notifiers: {} -# notifiers.yaml: -# notifiers: -# - name: email-notifier -# type: email -# uid: email1 -# # either: -# org_id: 1 -# # or -# org_name: Main Org. -# is_default: true -# settings: -# addresses: an_email_address@example.com -# delete_notifiers: - -## Configure grafana dashboard providers -## ref: http://docs.grafana.org/administration/provisioning/#dashboards -## -## `path` must be /var/lib/grafana/dashboards/ -## -dashboardProviders: {} -# dashboardproviders.yaml: -# apiVersion: 1 -# providers: -# - name: 'default' -# orgId: 1 -# folder: '' -# type: file -# disableDeletion: false -# editable: true -# options: -# path: /var/lib/grafana/dashboards/default - -## Configure grafana dashboard to import -## NOTE: To use dashboards you must also enable/configure dashboardProviders -## ref: https://grafana.com/dashboards -## -## dashboards per provider, use provider name as key. -## -dashboards: {} - # default: - # some-dashboard: - # json: | - # $RAW_JSON - # custom-dashboard: - # file: dashboards/custom-dashboard.json - # prometheus-stats: - # gnetId: 2 - # revision: 2 - # datasource: Prometheus - # local-dashboard: - # url: https://example.com/repository/test.json - # token: '' - # local-dashboard-base64: - # url: https://example.com/repository/test-b64.json - # token: '' - # b64content: true - # local-dashboard-gitlab: - # url: https://example.com/repository/test-gitlab.json - # gitlabToken: '' - # local-dashboard-bitbucket: - # url: https://example.com/repository/test-bitbucket.json - # bearerToken: '' - # local-dashboard-azure: - # url: https://example.com/repository/test-azure.json - # basic: '' - # acceptHeader: '*/*' - -## Reference to external ConfigMap per provider. Use provider name as key and ConfigMap name as value. -## A provider dashboards must be defined either by external ConfigMaps or in values.yaml, not in both. -## ConfigMap data example: -## -## data: -## example-dashboard.json: | -## RAW_JSON -## -dashboardsConfigMaps: {} -# default: "" - -## Grafana's primary configuration -## NOTE: values in map will be converted to ini format -## ref: http://docs.grafana.org/installation/configuration/ -## -grafana.ini: - paths: - data: /var/lib/grafana/ - logs: /var/log/grafana - plugins: /var/lib/grafana/plugins - provisioning: /etc/grafana/provisioning - analytics: - check_for_updates: true - log: - mode: console - grafana_net: - url: https://grafana.net - server: - domain: "{{ if (and .Values.ingress.enabled .Values.ingress.hosts) }}{{ .Values.ingress.hosts | first }}{{ else }}''{{ end }}" -## grafana Authentication can be enabled with the following values on grafana.ini - # server: - # The full public facing url you use in browser, used for redirects and emails - # root_url: - # https://grafana.com/docs/grafana/latest/auth/github/#enable-github-in-grafana - # auth.github: - # enabled: false - # allow_sign_up: false - # scopes: user:email,read:org - # auth_url: https://github.com/login/oauth/authorize - # token_url: https://github.com/login/oauth/access_token - # api_url: https://api.github.com/user - # team_ids: - # allowed_organizations: - # client_id: - # client_secret: -## LDAP Authentication can be enabled with the following values on grafana.ini -## NOTE: Grafana will fail to start if the value for ldap.toml is invalid - # auth.ldap: - # enabled: true - # allow_sign_up: true - # config_file: /etc/grafana/ldap.toml - -## Grafana's LDAP configuration -## Templated by the template in _helpers.tpl -## NOTE: To enable the grafana.ini must be configured with auth.ldap.enabled -## ref: http://docs.grafana.org/installation/configuration/#auth-ldap -## ref: http://docs.grafana.org/installation/ldap/#configuration -ldap: - enabled: false - # `existingSecret` is a reference to an existing secret containing the ldap configuration - # for Grafana in a key `ldap-toml`. - existingSecret: "" - # `config` is the content of `ldap.toml` that will be stored in the created secret - config: "" - # config: |- - # verbose_logging = true - - # [[servers]] - # host = "my-ldap-server" - # port = 636 - # use_ssl = true - # start_tls = false - # ssl_skip_verify = false - # bind_dn = "uid=%s,ou=users,dc=myorg,dc=com" - -## Grafana's SMTP configuration -## NOTE: To enable, grafana.ini must be configured with smtp.enabled -## ref: http://docs.grafana.org/installation/configuration/#smtp -smtp: - # `existingSecret` is a reference to an existing secret containing the smtp configuration - # for Grafana. - existingSecret: "" - userKey: "user" - passwordKey: "password" - -## Sidecars that collect the configmaps with specified label and stores the included files them into the respective folders -## Requires at least Grafana 5 to work and can't be used together with parameters dashboardProviders, datasources and dashboards -sidecar: - image: - repository: rancher/mirrored-kiwigrid-k8s-sidecar - tag: 1.27.4 - sha: "" - imagePullPolicy: IfNotPresent - resources: {} -# limits: -# cpu: 100m -# memory: 100Mi -# requests: -# cpu: 50m -# memory: 50Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - seccompProfile: - type: RuntimeDefault - # skipTlsVerify Set to true to skip tls verification for kube api calls - # skipTlsVerify: true - enableUniqueFilenames: false - readinessProbe: {} - livenessProbe: {} - # Log level default for all sidecars. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. Defaults to INFO - # logLevel: INFO - alerts: - enabled: false - # Additional environment variables for the alerts sidecar - env: {} - # Do not reprocess already processed unchanged resources on k8s API reconnect. - # ignoreAlreadyProcessed: true - # label that the configmaps with alert are marked with - label: grafana_alert - # value of label that the configmaps with alert are set to - labelValue: "" - # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. - # logLevel: INFO - # If specified, the sidecar will search for alert config-maps inside this namespace. - # 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. - watchMethod: WATCH - # search in configmap, secret or both - resource: both - # 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: 3600 - # - # 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 (sic!) - # watchClientTimeout: 60 - # - # Endpoint to send request to reload alerts - reloadURL: "http://localhost:3000/api/admin/provisioning/alerting/reload" - # Absolute path to shell script to execute after a alert got reloaded - script: null - skipReload: false - # This is needed if skipReload is true, to load any alerts defined at startup time. - # Deploy the alert sidecar as an initContainer. - initAlerts: false - # Additional alert sidecar volume mounts - extraMounts: [] - # Sets the size limit of the alert sidecar emptyDir volume - sizeLimit: {} - dashboards: - enabled: false - # Additional environment variables for the dashboards sidecar - env: {} - ## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. - ## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core - ## Renders in container spec as: - ## env: - ## ... - ## - name: - ## valueFrom: - ## - envValueFrom: {} - # ENV_NAME: - # configMapKeyRef: - # name: configmap-name - # key: value_key - # Do not reprocess already processed unchanged resources on k8s API reconnect. - # ignoreAlreadyProcessed: true - SCProvider: true - # label that the configmaps with dashboards are marked with - label: grafana_dashboard - # value of label that the configmaps with dashboards are set to - labelValue: "" - # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. - # logLevel: INFO - # folder in the pod that should hold the collected dashboards (unless `defaultFolderName` is set) - folder: /tmp/dashboards - # The default folder name, it will create a subfolder under the `folder` and put dashboards in there instead - defaultFolderName: null - # Namespaces list. 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. - watchMethod: WATCH - # search in configmap, secret or both - resource: both - # If specified, the sidecar will look for annotation with this name to create folder and put graph here. - # You can use this parameter together with `provider.foldersFromFilesStructure`to annotate configmaps and create folder structure. - folderAnnotation: null - # Endpoint to send request to reload alerts - reloadURL: "http://localhost:3000/api/admin/provisioning/dashboards/reload" - # Absolute path to shell script to execute after a configmap got reloaded - script: null - skipReload: false - # 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: 3600 - # - # 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 (sic!) - # watchClientTimeout: 60 - # - # provider configuration that lets grafana manage the dashboards - provider: - # name of the provider, should be unique - name: sidecarProvider - # orgid as configured in grafana - orgid: 1 - # folder in which the dashboards should be imported in grafana - folder: '' - # folder UID. will be automatically generated if not specified - folderUid: '' - # type of the provider - type: file - # disableDelete to activate a import-only behaviour - disableDelete: false - # allow updating provisioned dashboards from the UI - allowUiUpdates: false - # allow Grafana to replicate dashboard structure from filesystem - foldersFromFilesStructure: false - # Additional dashboard sidecar volume mounts - extraMounts: [] - # Sets the size limit of the dashboard sidecar emptyDir volume - sizeLimit: {} - datasources: - enabled: false - # Additional environment variables for the datasourcessidecar - env: {} - ## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. - ## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core - ## Renders in container spec as: - ## env: - ## ... - ## - name: - ## valueFrom: - ## - envValueFrom: {} - # ENV_NAME: - # configMapKeyRef: - # name: configmap-name - # key: value_key - # Do not reprocess already processed unchanged resources on k8s API reconnect. - # ignoreAlreadyProcessed: true - # label that the configmaps with datasources are marked with - label: grafana_datasource - # value of label that the configmaps with datasources are set to - labelValue: "" - # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. - # logLevel: INFO - # If specified, the sidecar will search for datasource config-maps inside this namespace. - # 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. - watchMethod: WATCH - # search in configmap, secret or both - resource: both - # 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: 3600 - # - # 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 (sic!) - # watchClientTimeout: 60 - # - # Endpoint to send request to reload datasources - reloadURL: "http://localhost:3000/api/admin/provisioning/datasources/reload" - # Absolute path to shell script to execute after a datasource got reloaded - script: null - skipReload: true - # This is needed if skipReload is true, to load any datasources defined at startup time. - # Deploy the datasources sidecar as an initContainer. - initDatasources: true - # Sets the size limit of the datasource sidecar emptyDir volume - sizeLimit: {} - plugins: - enabled: false - # Additional environment variables for the plugins sidecar - env: {} - # Do not reprocess already processed unchanged resources on k8s API reconnect. - # ignoreAlreadyProcessed: true - # label that the configmaps with plugins are marked with - label: grafana_plugin - # value of label that the configmaps with plugins are set to - labelValue: "" - # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. - # logLevel: INFO - # If specified, the sidecar will search for plugin config-maps inside this namespace. - # 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. - watchMethod: WATCH - # search in configmap, secret or both - resource: both - # 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: 3600 - # - # 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 (sic!) - # watchClientTimeout: 60 - # - # Endpoint to send request to reload plugins - reloadURL: "http://localhost:3000/api/admin/provisioning/plugins/reload" - # Absolute path to shell script to execute after a plugin got reloaded - script: null - skipReload: false - # Deploy the datasource sidecar as an initContainer in addition to a container. - # This is needed if skipReload is true, to load any plugins defined at startup time. - initPlugins: false - # Sets the size limit of the plugin sidecar emptyDir volume - sizeLimit: {} - notifiers: - enabled: false - # Additional environment variables for the notifierssidecar - env: {} - # Do not reprocess already processed unchanged resources on k8s API reconnect. - # ignoreAlreadyProcessed: true - # label that the configmaps with notifiers are marked with - label: grafana_notifier - # value of label that the configmaps with notifiers are set to - labelValue: "" - # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. - # logLevel: INFO - # If specified, the sidecar will search for notifier config-maps inside this namespace. - # 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. - watchMethod: WATCH - # search in configmap, secret or both - resource: both - # 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: 3600 - # - # 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 (sic!) - # watchClientTimeout: 60 - # - # Endpoint to send request to reload notifiers - reloadURL: "http://localhost:3000/api/admin/provisioning/notifications/reload" - # Absolute path to shell script to execute after a notifier got reloaded - script: null - skipReload: false - # Deploy the notifier sidecar as an initContainer in addition to a container. - # This is needed if skipReload is true, to load any notifiers defined at startup time. - initNotifiers: false - # Sets the size limit of the notifier sidecar emptyDir volume - sizeLimit: {} - -## Override the deployment namespace -## -namespaceOverride: "" - -## Number of old ReplicaSets to retain -## -revisionHistoryLimit: 10 - -## Add a seperate remote image renderer deployment/service -imageRenderer: - deploymentStrategy: {} - # Enable the image-renderer deployment & service - enabled: false - replicas: 1 - autoscaling: - enabled: false - minReplicas: 1 - maxReplicas: 5 - targetCPU: "60" - targetMemory: "" - behavior: {} - image: - # image-renderer Image repository - repository: rancher/mirrored-grafana-grafana-image-renderer - # image-renderer Image tag - tag: 3.11.1 - # image-renderer Image sha (optional) - sha: "" - # image-renderer ImagePullPolicy - pullPolicy: Always - # extra environment variables - env: - HTTP_HOST: "0.0.0.0" - # RENDERING_ARGS: --no-sandbox,--disable-gpu,--window-size=1280x758 - # RENDERING_MODE: clustered - # IGNORE_HTTPS_ERRORS: true - - ## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. - ## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core - ## Renders in container spec as: - ## env: - ## ... - ## - name: - ## valueFrom: - ## - envValueFrom: {} - # ENV_NAME: - # configMapKeyRef: - # name: configmap-name - # key: value_key - - # image-renderer deployment serviceAccount - serviceAccountName: "" - # image-renderer deployment securityContext - securityContext: {} - # image-renderer deployment container securityContext - containerSecurityContext: - seccompProfile: - type: RuntimeDefault - capabilities: - drop: ['ALL'] - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - ## image-renderer pod annotation - podAnnotations: {} - # image-renderer deployment Host Aliases - hostAliases: [] - # image-renderer deployment priority class - priorityClassName: '' - service: - # Enable the image-renderer service - enabled: true - # image-renderer service port name - portName: 'http' - # image-renderer service port used by both service and deployment - port: 8081 - targetPort: 8081 - # Adds the appProtocol field to the image-renderer service. This allows to work with istio protocol selection. Ex: "http" or "tcp" - appProtocol: "" - serviceMonitor: - ## If true, a ServiceMonitor CRD is created for a prometheus operator - ## https://github.com/coreos/prometheus-operator - ## - enabled: false - path: /metrics - # namespace: monitoring (defaults to use the namespace this chart is deployed to) - labels: {} - interval: 1m - scheme: http - tlsConfig: {} - scrapeTimeout: 30s - relabelings: [] - # See: https://doc.crds.dev/github.com/prometheus-operator/kube-prometheus/monitoring.coreos.com/ServiceMonitor/v1@v0.11.0#spec-targetLabels - targetLabels: [] - # - targetLabel1 - # - targetLabel2 - # If https is enabled in Grafana, this needs to be set as 'https' to correctly configure the callback used in Grafana - grafanaProtocol: http - # In case a sub_path is used this needs to be added to the image renderer callback - grafanaSubPath: "" - # name of the image-renderer port on the pod - podPortName: http - # number of image-renderer replica sets to keep - revisionHistoryLimit: 10 - networkPolicy: - # Enable a NetworkPolicy to limit inbound traffic to only the created grafana pods - limitIngress: true - # Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods - limitEgress: false - # Allow additional services to access image-renderer (eg. Prometheus operator when ServiceMonitor is enabled) - extraIngressSelectors: [] - resources: {} -# limits: -# cpu: 100m -# memory: 100Mi -# requests: -# cpu: 50m -# memory: 50Mi - ## Node labels for pod assignment - ## ref: https://kubernetes.io/docs/user-guide/node-selection/ - # - nodeSelector: {} - - ## Tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - ## - tolerations: [] - - ## Affinity for pod assignment (evaluated as template) - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - ## - affinity: {} - - ## Use an alternate scheduler, e.g. "stork". - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - # schedulerName: "default-scheduler" - - # Extra configmaps to mount in image-renderer pods - extraConfigmapMounts: [] - - # Extra secrets to mount in image-renderer pods - extraSecretMounts: [] - - # Extra volumes to mount in image-renderer pods - extraVolumeMounts: [] - - # Extra volumes for image-renderer pods - extraVolumes: [] - -networkPolicy: - ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. - ## - enabled: false - ## @param networkPolicy.allowExternal Don't require client label for connections - ## The Policy model to apply. When set to false, only pods with the correct - ## client label will have network access to grafana port defined. - ## When true, grafana will accept connections from any source - ## (with the correct destination port). - ## - ingress: true - ## @param networkPolicy.ingress When true enables the creation - ## an ingress network policy - ## - allowExternal: true - ## @param networkPolicy.explicitNamespacesSelector A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed - ## If explicitNamespacesSelector is missing or set to {}, only client Pods that are in the networkPolicy's namespace - ## and that match other criteria, the ones that have the good label, can reach the grafana. - ## But sometimes, we want the grafana to be accessible to clients from other namespaces, in this case, we can use this - ## LabelSelector to select these namespaces, note that the networkPolicy's namespace should also be explicitly added. - ## - ## Example: - ## explicitNamespacesSelector: - ## matchLabels: - ## role: frontend - ## matchExpressions: - ## - {key: role, operator: In, values: [frontend]} - ## - explicitNamespacesSelector: {} - ## - ## - ## - ## - ## - ## - egress: - ## @param networkPolicy.egress.enabled When enabled, an egress network policy will be - ## created allowing grafana to connect to external data sources from kubernetes cluster. - enabled: false - ## - ## @param networkPolicy.egress.blockDNSResolution When enabled, DNS resolution will be blocked - ## for all pods in the grafana namespace. - blockDNSResolution: false - ## - ## @param networkPolicy.egress.ports Add individual ports to be allowed by the egress - ports: [] - ## Add ports to the egress by specifying - port: - ## E.X. - ## - port: 80 - ## - port: 443 - ## - ## @param networkPolicy.egress.to Allow egress traffic to specific destinations - to: [] - ## Add destinations to the egress by specifying - ipBlock: - ## E.X. - ## to: - ## - namespaceSelector: - ## matchExpressions: - ## - {key: role, operator: In, values: [grafana]} - ## - ## - ## - ## - ## - -# Enable backward compatibility of kubernetes where version below 1.13 doesn't have the enableServiceLinks option -enableKubeBackwardCompatibility: false -useStatefulSet: false -# Create a dynamic manifests via values: -extraObjects: [] - # - apiVersion: "kubernetes-client.io/v1" - # kind: ExternalSecret - # metadata: - # name: grafana-secrets - # spec: - # backendType: gcpSecretsManager - # data: - # - key: grafana-admin-password - # name: adminPassword - -# assertNoLeakedSecrets is a helper function defined in _helpers.tpl that checks if secret -# values are not exposed in the rendered grafana.ini configmap. It is enabled by default. -# -# To pass values into grafana.ini without exposing them in a configmap, use variable expansion: -# https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#variable-expansion -# -# Alternatively, if you wish to allow secret values to be exposed in the rendered grafana.ini configmap, -# you can disable this check by setting assertNoLeakedSecrets to false. -assertNoLeakedSecrets: true diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/Chart.yaml deleted file mode 100644 index 980dcf9cfb..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: hardenedKubelet -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedKubelet/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/Chart.yaml deleted file mode 100644 index 759ed7c38d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: hardenedNodeExporter -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/hardenedNodeExporter/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/Chart.yaml deleted file mode 100644 index 39ed968500..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: k3sServer -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/k3sServer/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/.helmignore deleted file mode 100644 index f0c1319444..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/.helmignore +++ /dev/null @@ -1,21 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/Chart.yaml deleted file mode 100644 index 1360e832be..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/Chart.yaml +++ /dev/null @@ -1,32 +0,0 @@ -annotations: - artifacthub.io/license: Apache-2.0 - artifacthub.io/links: | - - name: Chart Source - url: https://github.com/prometheus-community/helm-charts - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-kube-state-metrics -apiVersion: v2 -appVersion: 2.12.0 -description: Install kube-state-metrics to generate and expose cluster-level metrics -home: https://github.com/kubernetes/kube-state-metrics/ -keywords: -- metric -- monitoring -- prometheus -- kubernetes -maintainers: -- email: tariq.ibrahim@mulesoft.com - name: tariq1890 -- email: manuel@rueg.eu - name: mrueg -- email: david@0xdc.me - name: dotdc -name: kube-state-metrics -sources: -- https://github.com/kubernetes/kube-state-metrics/ -type: application -version: 5.21.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/README.md deleted file mode 100644 index 843be89e69..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# kube-state-metrics Helm Chart - -Installs the [kube-state-metrics agent](https://github.com/kubernetes/kube-state-metrics). - -## Get Repository Info - -```console -helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -helm repo update -``` - -_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ - - -## Install Chart - -```console -helm install [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] -``` - -_See [configuration](#configuration) below._ - -_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ - -## Uninstall 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._ - -## Upgrading Chart - -```console -helm upgrade [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] -``` - -_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ - -### Migrating from stable/kube-state-metrics and kubernetes/kube-state-metrics - -You can upgrade in-place: - -1. [get repository info](#get-repository-info) -1. [upgrade](#upgrading-chart) your existing release name using the new chart repository - -## Upgrading to v3.0.0 - -v3.0.0 includes kube-state-metrics v2.0, see the [changelog](https://github.com/kubernetes/kube-state-metrics/blob/release-2.0/CHANGELOG.md) for major changes on the application-side. - -The upgraded chart now the following changes: - -* Dropped support for helm v2 (helm v3 or later is required) -* collectors key was renamed to resources -* namespace key was renamed to namespaces - -## Configuration - -See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: - -```console -helm show values prometheus-community/kube-state-metrics -``` - -### kube-rbac-proxy - -You can enable `kube-state-metrics` endpoint protection using `kube-rbac-proxy`. By setting `kubeRBACProxy.enabled: true`, this chart will deploy one RBAC proxy container per endpoint (metrics & telemetry). -To authorize access, authenticate your requests (via a `ServiceAccount` for example) with a `ClusterRole` attached such as: - -```yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: kube-state-metrics-read -rules: - - apiGroups: [ "" ] - resources: ["services/kube-state-metrics"] - verbs: - - get -``` - -See [kube-rbac-proxy examples](https://github.com/brancz/kube-rbac-proxy/tree/master/examples/resource-attributes) for more details. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/NOTES.txt deleted file mode 100644 index 3589c24ec3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/NOTES.txt +++ /dev/null @@ -1,23 +0,0 @@ -kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects. -The exposed metrics can be found here: -https://github.com/kubernetes/kube-state-metrics/blob/master/docs/README.md#exposed-metrics - -The metrics are exported on the HTTP endpoint /metrics on the listening port. -In your case, {{ template "kube-state-metrics.fullname" . }}.{{ template "kube-state-metrics.namespace" . }}.svc.cluster.local:{{ .Values.service.port }}/metrics - -They are served either as plaintext or protobuf depending on the Accept header. -They are designed to be consumed either by Prometheus itself or by a scraper that is compatible with scraping a Prometheus client endpoint. - -{{- if .Values.kubeRBACProxy.enabled}} - -kube-rbac-proxy endpoint protections is enabled: -- Metrics endpoints are now HTTPS -- Ensure that the client authenticates the requests (e.g. via service account) with the following role permissions: -``` -rules: - - apiGroups: [ "" ] - resources: ["services/{{ template "kube-state-metrics.fullname" . }}"] - verbs: - - get -``` -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/_helpers.tpl deleted file mode 100644 index ed277fbb53..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/_helpers.tpl +++ /dev/null @@ -1,196 +0,0 @@ -# Rancher -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -{{- define "monitoring_registry" -}} - {{- $temp_registry := (include "system_default_registry" .) -}} - {{- if $temp_registry -}} - {{- trimSuffix "/" $temp_registry -}} - {{- else -}} - {{- .Values.global.imageRegistry -}} - {{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "kube-state-metrics.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 "kube-state-metrics.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 "kube-state-metrics.serviceAccountName" -}} -{{- if .Values.serviceAccount.create -}} - {{ default (include "kube-state-metrics.fullname" .) .Values.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* -Allow the release namespace to be overridden for multi-namespace deployments in combined charts -*/}} -{{- define "kube-state-metrics.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "kube-state-metrics.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Generate basic labels -*/}} -{{- define "kube-state-metrics.labels" }} -helm.sh/chart: {{ template "kube-state-metrics.chart" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -app.kubernetes.io/component: metrics -app.kubernetes.io/part-of: {{ template "kube-state-metrics.name" . }} -{{- include "kube-state-metrics.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -{{- if .Values.customLabels }} -{{ toYaml .Values.customLabels }} -{{- end }} -{{- if .Values.releaseLabel }} -release: {{ .Release.Name }} -{{- end }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "kube-state-metrics.selectorLabels" }} -{{- if .Values.selectorOverride }} -{{ toYaml .Values.selectorOverride }} -{{- else }} -app.kubernetes.io/name: {{ include "kube-state-metrics.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} -{{- end }} - -{{/* Sets default scrape limits for servicemonitor */}} -{{- define "servicemonitor.scrapeLimits" -}} -{{- with .sampleLimit }} -sampleLimit: {{ . }} -{{- end }} -{{- with .targetLimit }} -targetLimit: {{ . }} -{{- end }} -{{- with .labelLimit }} -labelLimit: {{ . }} -{{- end }} -{{- with .labelNameLengthLimit }} -labelNameLengthLimit: {{ . }} -{{- end }} -{{- with .labelValueLengthLimit }} -labelValueLengthLimit: {{ . }} -{{- end }} -{{- end -}} - -{{/* -Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) -*/}} -{{- define "kube-state-metrics.imagePullSecrets" -}} -{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} - {{- if eq (typeOf .) "map[string]interface {}" }} -- {{ toYaml . | trim }} - {{- else }} -- name: {{ . }} - {{- end }} -{{- end }} -{{- end -}} - -{{/* -The image to use for kube-state-metrics -*/}} -{{- define "kube-state-metrics.image" -}} -{{- $registry := (include "monitoring_registry" .) }} -{{- if .Values.image.sha }} -{{- if $registry }} -{{- printf "%s/%s:%s@%s" $registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.sha }} -{{- else }} -{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.sha }} -{{- end }} -{{- else }} -{{- if $registry }} -{{- printf "%s/%s:%s" $registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} -{{- else }} -{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -The image to use for kubeRBACProxy -*/}} -{{- define "kubeRBACProxy.image" -}} -{{- $registry := (include "monitoring_registry" .) }} -{{- if .Values.kubeRBACProxy.image.sha }} -{{- if $registry }} -{{- printf "%s/%s:%s@%s" $registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) .Values.kubeRBACProxy.image.sha }} -{{- else }} -{{- printf "%s/%s:%s@%s" .Values.kubeRBACProxy.image.registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) .Values.kubeRBACProxy.image.sha }} -{{- end }} -{{- else }} -{{- if $registry }} -{{- printf "%s/%s:%s" $registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) }} -{{- else }} -{{- printf "%s/%s:%s" .Values.kubeRBACProxy.image.registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) }} -{{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml deleted file mode 100644 index 025cd47a88..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if and .Values.networkPolicy.enabled (eq .Values.networkPolicy.flavor "cilium") }} -apiVersion: cilium.io/v2 -kind: CiliumNetworkPolicy -metadata: - {{- if .Values.annotations }} - annotations: - {{ toYaml .Values.annotations | nindent 4 }} - {{- end }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - name: {{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} -spec: - endpointSelector: - matchLabels: - {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} - egress: - {{- if and .Values.networkPolicy.cilium .Values.networkPolicy.cilium.kubeApiServerSelector }} - {{ toYaml .Values.networkPolicy.cilium.kubeApiServerSelector | nindent 6 }} - {{- else }} - - toEntities: - - kube-apiserver - {{- end }} - ingress: - - toPorts: - - ports: - - port: {{ .Values.service.port | quote }} - protocol: TCP - {{- if .Values.selfMonitor.enabled }} - - port: {{ .Values.selfMonitor.telemetryPort | default 8081 | quote }} - protocol: TCP - {{ end }} -{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/clusterrolebinding.yaml deleted file mode 100644 index cf9f628d04..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/clusterrolebinding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.rbac.create .Values.rbac.useClusterRole -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - name: {{ template "kube-state-metrics.fullname" . }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole -{{- if .Values.rbac.useExistingRole }} - name: {{ .Values.rbac.useExistingRole }} -{{- else }} - name: {{ template "kube-state-metrics.fullname" . }} -{{- end }} -subjects: -- kind: ServiceAccount - name: {{ template "kube-state-metrics.serviceAccountName" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/crs-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/crs-configmap.yaml deleted file mode 100644 index d38a75a51d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/crs-configmap.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.customResourceState.enabled}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "kube-state-metrics.fullname" . }}-customresourcestate-config - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - {{- if .Values.annotations }} - annotations: - {{ toYaml .Values.annotations | nindent 4 }} - {{- end }} -data: - config.yaml: | - {{- toYaml .Values.customResourceState.config | nindent 4 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/deployment.yaml deleted file mode 100644 index 2c63048cc6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/deployment.yaml +++ /dev/null @@ -1,313 +0,0 @@ -apiVersion: apps/v1 -{{- if .Values.autosharding.enabled }} -kind: StatefulSet -{{- else }} -kind: Deployment -{{- end }} -metadata: - name: {{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - {{- if .Values.annotations }} - annotations: -{{ toYaml .Values.annotations | indent 4 }} - {{- end }} -spec: - selector: - matchLabels: - {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} - replicas: {{ .Values.replicas }} - {{- if not .Values.autosharding.enabled }} - strategy: - type: {{ .Values.updateStrategy | default "RollingUpdate" }} - {{- end }} - revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} - {{- if .Values.autosharding.enabled }} - serviceName: {{ template "kube-state-metrics.fullname" . }} - volumeClaimTemplates: [] - {{- end }} - template: - metadata: - labels: - {{- include "kube-state-metrics.labels" . | indent 8 }} - {{- if .Values.podAnnotations }} - annotations: -{{ toYaml .Values.podAnnotations | indent 8 }} - {{- end }} - spec: - automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} - hostNetwork: {{ .Values.hostNetwork }} - serviceAccountName: {{ template "kube-state-metrics.serviceAccountName" . }} - {{- if .Values.securityContext.enabled }} - securityContext: {{- omit .Values.securityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - {{- if .Values.priorityClassName }} - priorityClassName: {{ .Values.priorityClassName }} - {{- end }} - {{- with .Values.initContainers }} - initContainers: - {{- toYaml . | nindent 6 }} - {{- end }} - containers: - {{- $servicePort := ternary 9090 (.Values.service.port | default 8080) .Values.kubeRBACProxy.enabled}} - {{- $telemetryPort := ternary 9091 (.Values.selfMonitor.telemetryPort | default 8081) .Values.kubeRBACProxy.enabled}} - - name: {{ template "kube-state-metrics.name" . }} - {{- if .Values.autosharding.enabled }} - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - {{- end }} - args: - {{- if .Values.extraArgs }} - {{- .Values.extraArgs | toYaml | nindent 8 }} - {{- end }} - - --port={{ $servicePort }} - {{- if .Values.collectors }} - - --resources={{ .Values.collectors | join "," }} - {{- end }} - {{- if .Values.metricLabelsAllowlist }} - - --metric-labels-allowlist={{ .Values.metricLabelsAllowlist | join "," }} - {{- end }} - {{- if .Values.metricAnnotationsAllowList }} - - --metric-annotations-allowlist={{ .Values.metricAnnotationsAllowList | join "," }} - {{- end }} - {{- if .Values.metricAllowlist }} - - --metric-allowlist={{ .Values.metricAllowlist | join "," }} - {{- end }} - {{- if .Values.metricDenylist }} - - --metric-denylist={{ .Values.metricDenylist | join "," }} - {{- end }} - {{- $namespaces := list }} - {{- if .Values.namespaces }} - {{- range $ns := join "," .Values.namespaces | split "," }} - {{- $namespaces = append $namespaces (tpl $ns $) }} - {{- end }} - {{- end }} - {{- if .Values.releaseNamespace }} - {{- $namespaces = append $namespaces ( include "kube-state-metrics.namespace" . ) }} - {{- end }} - {{- if $namespaces }} - - --namespaces={{ $namespaces | mustUniq | join "," }} - {{- end }} - {{- if .Values.namespacesDenylist }} - - --namespaces-denylist={{ tpl (.Values.namespacesDenylist | join ",") $ }} - {{- end }} - {{- if .Values.autosharding.enabled }} - - --pod=$(POD_NAME) - - --pod-namespace=$(POD_NAMESPACE) - {{- end }} - {{- if .Values.kubeconfig.enabled }} - - --kubeconfig=/opt/k8s/.kube/config - {{- end }} - {{- if .Values.kubeRBACProxy.enabled }} - - --telemetry-host=127.0.0.1 - - --telemetry-port={{ $telemetryPort }} - {{- else }} - {{- if .Values.selfMonitor.telemetryHost }} - - --telemetry-host={{ .Values.selfMonitor.telemetryHost }} - {{- end }} - {{- if .Values.selfMonitor.telemetryPort }} - - --telemetry-port={{ $telemetryPort }} - {{- end }} - {{- end }} - {{- if .Values.customResourceState.enabled }} - - --custom-resource-state-config-file=/etc/customresourcestate/config.yaml - {{- end }} - {{- if or (.Values.kubeconfig.enabled) (.Values.customResourceState.enabled) (.Values.volumeMounts) }} - volumeMounts: - {{- if .Values.kubeconfig.enabled }} - - name: kubeconfig - mountPath: /opt/k8s/.kube/ - readOnly: true - {{- end }} - {{- if .Values.customResourceState.enabled }} - - name: customresourcestate-config - mountPath: /etc/customresourcestate - readOnly: true - {{- end }} - {{- if .Values.volumeMounts }} -{{ toYaml .Values.volumeMounts | indent 8 }} - {{- end }} - {{- end }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - image: {{ include "kube-state-metrics.image" . }} - {{- if eq .Values.kubeRBACProxy.enabled false }} - ports: - - containerPort: {{ .Values.service.port | default 8080}} - name: "http" - {{- if .Values.selfMonitor.enabled }} - - containerPort: {{ $telemetryPort }} - name: "metrics" - {{- end }} - {{- end }} - livenessProbe: - failureThreshold: {{ .Values.livenessProbe.failureThreshold }} - httpGet: - {{- if .Values.hostNetwork }} - host: 127.0.0.1 - {{- end }} - httpHeaders: - {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} - - name: {{ $header.name }} - value: {{ $header.value }} - {{- end }} - path: /healthz - port: {{ $servicePort }} - scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} - initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.livenessProbe.periodSeconds }} - successThreshold: {{ .Values.livenessProbe.successThreshold }} - timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} - readinessProbe: - failureThreshold: {{ .Values.readinessProbe.failureThreshold }} - httpGet: - {{- if .Values.hostNetwork }} - host: 127.0.0.1 - {{- end }} - httpHeaders: - {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} - - name: {{ $header.name }} - value: {{ $header.value }} - {{- end }} - path: / - port: {{ $servicePort }} - scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} - initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.readinessProbe.periodSeconds }} - successThreshold: {{ .Values.readinessProbe.successThreshold }} - timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} - resources: -{{ toYaml .Values.resources | indent 10 }} -{{- if .Values.containerSecurityContext }} - securityContext: -{{ toYaml .Values.containerSecurityContext | indent 10 }} -{{- end }} - {{- if .Values.kubeRBACProxy.enabled }} - - name: kube-rbac-proxy-http - args: - {{- if .Values.kubeRBACProxy.extraArgs }} - {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 8 }} - {{- end }} - - --secure-listen-address=:{{ .Values.service.port | default 8080}} - - --upstream=http://127.0.0.1:{{ $servicePort }}/ - - --proxy-endpoints-port=8888 - - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml - volumeMounts: - - name: kube-rbac-proxy-config - mountPath: /etc/kube-rbac-proxy-config - {{- with .Values.kubeRBACProxy.volumeMounts }} - {{- toYaml . | nindent 10 }} - {{- end }} - imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} - image: {{ include "kubeRBACProxy.image" . }} - ports: - - containerPort: {{ .Values.service.port | default 8080}} - name: "http" - - containerPort: 8888 - name: "http-healthz" - readinessProbe: - httpGet: - scheme: HTTPS - port: 8888 - path: healthz - initialDelaySeconds: 5 - timeoutSeconds: 5 - {{- if .Values.kubeRBACProxy.resources }} - resources: -{{ toYaml .Values.kubeRBACProxy.resources | indent 10 }} -{{- end }} -{{- if .Values.kubeRBACProxy.containerSecurityContext }} - securityContext: -{{ toYaml .Values.kubeRBACProxy.containerSecurityContext | indent 10 }} -{{- end }} - {{- if .Values.selfMonitor.enabled }} - - name: kube-rbac-proxy-telemetry - args: - {{- if .Values.kubeRBACProxy.extraArgs }} - {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 8 }} - {{- end }} - - --secure-listen-address=:{{ .Values.selfMonitor.telemetryPort | default 8081 }} - - --upstream=http://127.0.0.1:{{ $telemetryPort }}/ - - --proxy-endpoints-port=8889 - - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml - volumeMounts: - - name: kube-rbac-proxy-config - mountPath: /etc/kube-rbac-proxy-config - {{- with .Values.kubeRBACProxy.volumeMounts }} - {{- toYaml . | nindent 10 }} - {{- end }} - imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} - image: {{ include "kubeRBACProxy.image" . }} - ports: - - containerPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} - name: "metrics" - - containerPort: 8889 - name: "metrics-healthz" - readinessProbe: - httpGet: - scheme: HTTPS - port: 8889 - path: healthz - initialDelaySeconds: 5 - timeoutSeconds: 5 - {{- if .Values.kubeRBACProxy.resources }} - resources: -{{ toYaml .Values.kubeRBACProxy.resources | indent 10 }} -{{- end }} -{{- if .Values.kubeRBACProxy.containerSecurityContext }} - securityContext: -{{ toYaml .Values.kubeRBACProxy.containerSecurityContext | indent 10 }} -{{- end }} - {{- end }} - {{- end }} - {{- with .Values.containers }} - {{- toYaml . | nindent 6 }} - {{- end }} -{{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- include "kube-state-metrics.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} - {{- end }} - {{- if .Values.affinity }} - affinity: -{{ toYaml .Values.affinity | indent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} - {{- if .Values.nodeSelector }} -{{ toYaml .Values.nodeSelector | indent 8 }} - {{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} - {{- if .Values.tolerations }} -{{ toYaml .Values.tolerations | indent 8 }} - {{- end }} - {{- if .Values.topologySpreadConstraints }} - topologySpreadConstraints: -{{ toYaml .Values.topologySpreadConstraints | indent 8 }} - {{- end }} - {{- if or (.Values.kubeconfig.enabled) (.Values.customResourceState.enabled) (.Values.volumes) (.Values.kubeRBACProxy.enabled) }} - volumes: - {{- if .Values.kubeconfig.enabled}} - - name: kubeconfig - secret: - secretName: {{ template "kube-state-metrics.fullname" . }}-kubeconfig - {{- end }} - {{- if .Values.kubeRBACProxy.enabled}} - - name: kube-rbac-proxy-config - configMap: - name: {{ template "kube-state-metrics.fullname" . }}-rbac-config - {{- end }} - {{- if .Values.customResourceState.enabled}} - - name: customresourcestate-config - configMap: - name: {{ template "kube-state-metrics.fullname" . }}-customresourcestate-config - {{- end }} - {{- if .Values.volumes }} -{{ toYaml .Values.volumes | indent 8 }} - {{- end }} - {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/extra-manifests.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/extra-manifests.yaml deleted file mode 100644 index 567f7bf329..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/extra-manifests.yaml +++ /dev/null @@ -1,4 +0,0 @@ -{{ range .Values.extraManifests }} ---- -{{ tpl (toYaml .) $ }} -{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/kubeconfig-secret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/kubeconfig-secret.yaml deleted file mode 100644 index 6af0084502..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/kubeconfig-secret.yaml +++ /dev/null @@ -1,12 +0,0 @@ -{{- if .Values.kubeconfig.enabled -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "kube-state-metrics.fullname" . }}-kubeconfig - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} -type: Opaque -data: - config: '{{ .Values.kubeconfig.secret }}' -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/networkpolicy.yaml deleted file mode 100644 index 309b38ec54..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/networkpolicy.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if and .Values.networkPolicy.enabled (eq .Values.networkPolicy.flavor "kubernetes") }} -kind: NetworkPolicy -apiVersion: networking.k8s.io/v1 -metadata: - {{- if .Values.annotations }} - annotations: - {{ toYaml .Values.annotations | nindent 4 }} - {{- end }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - name: {{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} -spec: - {{- if .Values.networkPolicy.egress }} - ## Deny all egress by default - egress: - {{- toYaml .Values.networkPolicy.egress | nindent 4 }} - {{- end }} - ingress: - {{- if .Values.networkPolicy.ingress }} - {{- toYaml .Values.networkPolicy.ingress | nindent 4 }} - {{- else }} - ## Allow ingress on default ports by default - - ports: - - port: {{ .Values.service.port | default 8080 }} - protocol: TCP - {{- if .Values.selfMonitor.enabled }} - {{- $telemetryPort := ternary 9091 (.Values.selfMonitor.telemetryPort | default 8081) .Values.kubeRBACProxy.enabled}} - - port: {{ $telemetryPort }} - protocol: TCP - {{- end }} - {{- end }} - podSelector: - {{- if .Values.networkPolicy.podSelector }} - {{- toYaml .Values.networkPolicy.podSelector | nindent 4 }} - {{- else }} - matchLabels: - {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} - {{- end }} - policyTypes: - - Ingress - - Egress -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/pdb.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/pdb.yaml deleted file mode 100644 index 3771b511de..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/pdb.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.podDisruptionBudget -}} -{{ if $.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" -}} -apiVersion: policy/v1 -{{- else -}} -apiVersion: policy/v1beta1 -{{- end }} -kind: PodDisruptionBudget -metadata: - name: {{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} -spec: - selector: - matchLabels: - app.kubernetes.io/name: {{ template "kube-state-metrics.name" . }} -{{ toYaml .Values.podDisruptionBudget | indent 2 }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/podsecuritypolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/podsecuritypolicy.yaml deleted file mode 100644 index 8905e113e8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/podsecuritypolicy.yaml +++ /dev/null @@ -1,39 +0,0 @@ -{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "kube-state-metrics.fullname" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} -{{- if .Values.podSecurityPolicy.annotations }} - annotations: -{{ toYaml .Values.podSecurityPolicy.annotations | indent 4 }} -{{- end }} -spec: - privileged: false - volumes: - - 'secret' -{{- if .Values.podSecurityPolicy.additionalVolumes }} -{{ toYaml .Values.podSecurityPolicy.additionalVolumes | indent 4 }} -{{- end }} - hostNetwork: false - hostIPC: false - hostPID: false - runAsUser: - rule: 'MustRunAsNonRoot' - seLinux: - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - # Forbid adding the root group. - - min: 1 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - # Forbid adding the root group. - - min: 1 - max: 65535 - readOnlyRootFilesystem: false -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrole.yaml deleted file mode 100644 index 654e4a3d57..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrole.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - name: psp-{{ template "kube-state-metrics.fullname" . }} -rules: -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} -- apiGroups: ['policy'] -{{- else }} -- apiGroups: ['extensions'] -{{- end }} - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "kube-state-metrics.fullname" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml deleted file mode 100644 index 5b62a18bdf..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - name: psp-{{ template "kube-state-metrics.fullname" . }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: psp-{{ template "kube-state-metrics.fullname" . }} -subjects: - - kind: ServiceAccount - name: {{ template "kube-state-metrics.serviceAccountName" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/rbac-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/rbac-configmap.yaml deleted file mode 100644 index 671dc9d660..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/rbac-configmap.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- if .Values.kubeRBACProxy.enabled}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "kube-state-metrics.fullname" . }}-rbac-config - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - {{- if .Values.annotations }} - annotations: - {{ toYaml .Values.annotations | nindent 4 }} - {{- end }} -data: - config-file.yaml: |+ - authorization: - resourceAttributes: - namespace: {{ template "kube-state-metrics.namespace" . }} - apiVersion: v1 - resource: services - subresource: {{ template "kube-state-metrics.fullname" . }} - name: {{ template "kube-state-metrics.fullname" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/role.yaml deleted file mode 100644 index 0170878376..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/role.yaml +++ /dev/null @@ -1,215 +0,0 @@ -{{- if not (kindIs "slice" .Values.collectors) }} -{{- fail "Collectors need to be a List since kube-state-metrics chart 3.2.2. Please check README for more information."}} -{{- end }} -{{- if and (eq .Values.rbac.create true) (not .Values.rbac.useExistingRole) -}} -{{- range (ternary (join "," .Values.namespaces | split "," ) (list "") (eq $.Values.rbac.useClusterRole false)) }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -{{- if eq $.Values.rbac.useClusterRole false }} -kind: Role -{{- else }} -kind: ClusterRole -{{- end }} -metadata: - labels: - {{- include "kube-state-metrics.labels" $ | indent 4 }} - name: {{ template "kube-state-metrics.fullname" $ }} -{{- if eq $.Values.rbac.useClusterRole false }} - namespace: {{ . }} -{{- end }} -rules: -{{ if has "certificatesigningrequests" $.Values.collectors }} -- apiGroups: ["certificates.k8s.io"] - resources: - - certificatesigningrequests - verbs: ["list", "watch"] -{{ end -}} -{{ if has "configmaps" $.Values.collectors }} -- apiGroups: [""] - resources: - - configmaps - verbs: ["list", "watch"] -{{ end -}} -{{ if has "cronjobs" $.Values.collectors }} -- apiGroups: ["batch"] - resources: - - cronjobs - verbs: ["list", "watch"] -{{ end -}} -{{ if has "daemonsets" $.Values.collectors }} -- apiGroups: ["extensions", "apps"] - resources: - - daemonsets - verbs: ["list", "watch"] -{{ end -}} -{{ if has "deployments" $.Values.collectors }} -- apiGroups: ["extensions", "apps"] - resources: - - deployments - verbs: ["list", "watch"] -{{ end -}} -{{ if has "endpoints" $.Values.collectors }} -- apiGroups: [""] - resources: - - endpoints - verbs: ["list", "watch"] -{{ end -}} -{{ if has "endpointslices" $.Values.collectors }} -- apiGroups: ["discovery.k8s.io"] - resources: - - endpointslices - verbs: ["list", "watch"] -{{ end -}} -{{ if has "horizontalpodautoscalers" $.Values.collectors }} -- apiGroups: ["autoscaling"] - resources: - - horizontalpodautoscalers - verbs: ["list", "watch"] -{{ end -}} -{{ if has "ingresses" $.Values.collectors }} -- apiGroups: ["extensions", "networking.k8s.io"] - resources: - - ingresses - verbs: ["list", "watch"] -{{ end -}} -{{ if has "jobs" $.Values.collectors }} -- apiGroups: ["batch"] - resources: - - jobs - verbs: ["list", "watch"] -{{ end -}} -{{ if has "leases" $.Values.collectors }} -- apiGroups: ["coordination.k8s.io"] - resources: - - leases - verbs: ["list", "watch"] -{{ end -}} -{{ if has "limitranges" $.Values.collectors }} -- apiGroups: [""] - resources: - - limitranges - verbs: ["list", "watch"] -{{ end -}} -{{ if has "mutatingwebhookconfigurations" $.Values.collectors }} -- apiGroups: ["admissionregistration.k8s.io"] - resources: - - mutatingwebhookconfigurations - verbs: ["list", "watch"] -{{ end -}} -{{ if has "namespaces" $.Values.collectors }} -- apiGroups: [""] - resources: - - namespaces - verbs: ["list", "watch"] -{{ end -}} -{{ if has "networkpolicies" $.Values.collectors }} -- apiGroups: ["networking.k8s.io"] - resources: - - networkpolicies - verbs: ["list", "watch"] -{{ end -}} -{{ if has "nodes" $.Values.collectors }} -- apiGroups: [""] - resources: - - nodes - verbs: ["list", "watch"] -{{ end -}} -{{ if has "persistentvolumeclaims" $.Values.collectors }} -- apiGroups: [""] - resources: - - persistentvolumeclaims - verbs: ["list", "watch"] -{{ end -}} -{{ if has "persistentvolumes" $.Values.collectors }} -- apiGroups: [""] - resources: - - persistentvolumes - verbs: ["list", "watch"] -{{ end -}} -{{ if has "poddisruptionbudgets" $.Values.collectors }} -- apiGroups: ["policy"] - resources: - - poddisruptionbudgets - verbs: ["list", "watch"] -{{ end -}} -{{ if has "pods" $.Values.collectors }} -- apiGroups: [""] - resources: - - pods - verbs: ["list", "watch"] -{{ end -}} -{{ if has "replicasets" $.Values.collectors }} -- apiGroups: ["extensions", "apps"] - resources: - - replicasets - verbs: ["list", "watch"] -{{ end -}} -{{ if has "replicationcontrollers" $.Values.collectors }} -- apiGroups: [""] - resources: - - replicationcontrollers - verbs: ["list", "watch"] -{{ end -}} -{{ if has "resourcequotas" $.Values.collectors }} -- apiGroups: [""] - resources: - - resourcequotas - verbs: ["list", "watch"] -{{ end -}} -{{ if has "secrets" $.Values.collectors }} -- apiGroups: [""] - resources: - - secrets - verbs: ["list", "watch"] -{{ end -}} -{{ if has "services" $.Values.collectors }} -- apiGroups: [""] - resources: - - services - verbs: ["list", "watch"] -{{ end -}} -{{ if has "statefulsets" $.Values.collectors }} -- apiGroups: ["apps"] - resources: - - statefulsets - verbs: ["list", "watch"] -{{ end -}} -{{ if has "storageclasses" $.Values.collectors }} -- apiGroups: ["storage.k8s.io"] - resources: - - storageclasses - verbs: ["list", "watch"] -{{ end -}} -{{ if has "validatingwebhookconfigurations" $.Values.collectors }} -- apiGroups: ["admissionregistration.k8s.io"] - resources: - - validatingwebhookconfigurations - verbs: ["list", "watch"] -{{ end -}} -{{ if has "volumeattachments" $.Values.collectors }} -- apiGroups: ["storage.k8s.io"] - resources: - - volumeattachments - verbs: ["list", "watch"] -{{ end -}} -{{- if $.Values.kubeRBACProxy.enabled }} -- apiGroups: ["authentication.k8s.io"] - resources: - - tokenreviews - verbs: ["create"] -- apiGroups: ["authorization.k8s.io"] - resources: - - subjectaccessreviews - verbs: ["create"] -{{- end }} -{{- if $.Values.customResourceState.enabled }} -- apiGroups: ["apiextensions.k8s.io"] - resources: - - customresourcedefinitions - verbs: ["list", "watch"] -{{- end }} -{{ if $.Values.rbac.extraRules }} -{{ toYaml $.Values.rbac.extraRules }} -{{ end }} -{{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/rolebinding.yaml deleted file mode 100644 index 330651b73f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/rolebinding.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if and (eq .Values.rbac.create true) (eq .Values.rbac.useClusterRole false) -}} -{{- range (join "," $.Values.namespaces) | split "," }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - {{- include "kube-state-metrics.labels" $ | indent 4 }} - name: {{ template "kube-state-metrics.fullname" $ }} - namespace: {{ . }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role -{{- if (not $.Values.rbac.useExistingRole) }} - name: {{ template "kube-state-metrics.fullname" $ }} -{{- else }} - name: {{ $.Values.rbac.useExistingRole }} -{{- end }} -subjects: -- kind: ServiceAccount - name: {{ template "kube-state-metrics.serviceAccountName" $ }} - namespace: {{ template "kube-state-metrics.namespace" $ }} -{{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/service.yaml deleted file mode 100644 index 90c235148f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/service.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - annotations: - {{- if .Values.prometheusScrape }} - prometheus.io/scrape: '{{ .Values.prometheusScrape }}' - {{- end }} - {{- if .Values.service.annotations }} - {{- toYaml .Values.service.annotations | nindent 4 }} - {{- end }} -spec: - type: "{{ .Values.service.type }}" - {{- if .Values.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} - {{- end }} - ports: - - name: "http" - protocol: TCP - port: {{ .Values.service.port | default 8080}} - {{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} - targetPort: {{ .Values.service.port | default 8080}} - {{ if .Values.selfMonitor.enabled }} - - name: "metrics" - protocol: TCP - port: {{ .Values.selfMonitor.telemetryPort | default 8081 }} - targetPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} - {{- if .Values.selfMonitor.telemetryNodePort }} - nodePort: {{ .Values.selfMonitor.telemetryNodePort }} - {{- end }} - {{ end }} -{{- if .Values.service.loadBalancerIP }} - loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" -{{- end }} -{{- if .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} -{{- if .Values.autosharding.enabled }} - clusterIP: None -{{- else if .Values.service.clusterIP }} - clusterIP: "{{ .Values.service.clusterIP }}" -{{- end }} - selector: - {{- include "kube-state-metrics.selectorLabels" . | indent 4 }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/serviceaccount.yaml deleted file mode 100644 index c302bc7ca0..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/serviceaccount.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} -metadata: - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - name: {{ template "kube-state-metrics.serviceAccountName" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} -{{- if .Values.serviceAccount.annotations }} - annotations: -{{ toYaml .Values.serviceAccount.annotations | indent 4 }} -{{- end }} -{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} -imagePullSecrets: - {{- include "kube-state-metrics.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} -{{- end }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/servicemonitor.yaml deleted file mode 100644 index 577981b080..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/servicemonitor.yaml +++ /dev/null @@ -1,126 +0,0 @@ -{{- if .Values.prometheus.monitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} - {{- with .Values.prometheus.monitor.additionalLabels }} - {{- tpl (toYaml . | nindent 4) $ }} - {{- end }} - {{- with .Values.prometheus.monitor.annotations }} - annotations: - {{- tpl (toYaml . | nindent 4) $ }} - {{- end }} -spec: - jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} - {{- with .Values.prometheus.monitor.targetLabels }} - targetLabels: - {{- toYaml . | trim | nindent 4 }} - {{- end }} - {{- with .Values.prometheus.monitor.podTargetLabels }} - podTargetLabels: - {{- toYaml . | trim | nindent 4 }} - {{- end }} - {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | indent 2 }} - {{- if .Values.prometheus.monitor.namespaceSelector }} - namespaceSelector: - matchNames: - {{- with .Values.prometheus.monitor.namespaceSelector }} - {{- toYaml . | nindent 6 }} - {{- end }} - {{- end }} - selector: - matchLabels: - {{- with .Values.prometheus.monitor.selectorOverride }} - {{- toYaml . | nindent 6 }} - {{- else }} - {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} - {{- end }} - endpoints: - - port: http - {{- if or .Values.prometheus.monitor.http.interval .Values.prometheus.monitor.interval }} - interval: {{ .Values.prometheus.monitor.http.interval | default .Values.prometheus.monitor.interval }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.scrapeTimeout .Values.prometheus.monitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.prometheus.monitor.http.scrapeTimeout | default .Values.prometheus.monitor.scrapeTimeout }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.proxyUrl .Values.prometheus.monitor.proxyUrl }} - proxyUrl: {{ .Values.prometheus.monitor.http.proxyUrl | default .Values.prometheus.monitor.proxyUrl }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.enableHttp2 .Values.prometheus.monitor.enableHttp2 }} - enableHttp2: {{ .Values.prometheus.monitor.http.enableHttp2 | default .Values.prometheus.monitor.enableHttp2 }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.honorLabels .Values.prometheus.monitor.honorLabels }} - honorLabels: true - {{- end }} - metricRelabelings: - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName }} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.metricRelabelings .Values.prometheus.monitor.metricRelabelings }} - {{- toYaml (.Values.prometheus.monitor.http.metricRelabelings | default .Values.prometheus.monitor.metricRelabelings) | nindent 8 }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.relabelings .Values.prometheus.monitor.relabelings }} - relabelings: - {{- toYaml (.Values.prometheus.monitor.http.relabelings | default .Values.prometheus.monitor.relabelings) | nindent 8 }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.scheme .Values.prometheus.monitor.scheme }} - scheme: {{ .Values.prometheus.monitor.http.scheme | default .Values.prometheus.monitor.scheme }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.tlsConfig .Values.prometheus.monitor.tlsConfig }} - tlsConfig: - {{- toYaml (.Values.prometheus.monitor.http.tlsConfig | default .Values.prometheus.monitor.tlsConfig) | nindent 8 }} - {{- end }} - {{- if or .Values.prometheus.monitor.http.bearerTokenFile .Values.prometheus.monitor.bearerTokenFile }} - bearerTokenFile: {{ .Values.prometheus.monitor.http.bearerTokenFile | default .Values.prometheus.monitor.bearerTokenFile }} - {{- end }} - {{- with (.Values.prometheus.monitor.http.bearerTokenSecret | default .Values.prometheus.monitor.bearerTokenSecret) }} - bearerTokenSecret: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- if .Values.selfMonitor.enabled }} - - port: metrics - {{- if or .Values.prometheus.monitor.metrics.interval .Values.prometheus.monitor.interval }} - interval: {{ .Values.prometheus.monitor.metrics.interval | default .Values.prometheus.monitor.interval }} - {{- end }} - {{- if or .Values.prometheus.monitor.metrics.scrapeTimeout .Values.prometheus.monitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.prometheus.monitor.metrics.scrapeTimeout | default .Values.prometheus.monitor.scrapeTimeout }} - {{- end }} - {{- if or .Values.prometheus.monitor.metrics.proxyUrl .Values.prometheus.monitor.proxyUrl }} - proxyUrl: {{ .Values.prometheus.monitor.metrics.proxyUrl | default .Values.prometheus.monitor.proxyUrl }} - {{- end }} - {{- if or .Values.prometheus.monitor.metrics.enableHttp2 .Values.prometheus.monitor.enableHttp2 }} - enableHttp2: {{ .Values.prometheus.monitor.metrics.enableHttp2 | default .Values.prometheus.monitor.enableHttp2 }} - {{- end }} - {{- if or .Values.prometheus.monitor.metrics.honorLabels .Values.prometheus.monitor.honorLabels }} - honorLabels: true - {{- end }} - {{- if or .Values.prometheus.monitor.metrics.relabelings .Values.prometheus.monitor.relabelings }} - relabelings: - {{- toYaml (.Values.prometheus.monitor.metrics.relabelings | default .Values.prometheus.monitor.relabelings) | nindent 8 }} - {{- end }} - {{- if or .Values.prometheus.monitor.metrics.scheme .Values.prometheus.monitor.scheme }} - scheme: {{ .Values.prometheus.monitor.metrics.scheme | default .Values.prometheus.monitor.scheme }} - {{- end }} - {{- if or .Values.prometheus.monitor.metrics.tlsConfig .Values.prometheus.monitor.tlsConfig }} - tlsConfig: - {{- toYaml (.Values.prometheus.monitor.metrics.tlsConfig | default .Values.prometheus.monitor.tlsConfig) | nindent 8 }} - {{- end }} - {{- if or .Values.prometheus.monitor.metrics.bearerTokenFile .Values.prometheus.monitor.bearerTokenFile }} - bearerTokenFile: {{ .Values.prometheus.monitor.metrics.bearerTokenFile | default .Values.prometheus.monitor.bearerTokenFile }} - {{- end }} - {{- with (.Values.prometheus.monitor.metrics.bearerTokenSecret | default .Values.prometheus.monitor.bearerTokenSecret) }} - bearerTokenSecret: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-role.yaml deleted file mode 100644 index 489de147c1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-role.yaml +++ /dev/null @@ -1,26 +0,0 @@ -{{- if and .Values.autosharding.enabled .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} -rules: -- apiGroups: - - "" - resources: - - pods - verbs: - - get -- apiGroups: - - apps - resourceNames: - - {{ template "kube-state-metrics.fullname" . }} - resources: - - statefulsets - verbs: - - get - - list - - watch -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml deleted file mode 100644 index 73b37a4f64..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.autosharding.enabled .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} -subjects: - - kind: ServiceAccount - name: {{ template "kube-state-metrics.serviceAccountName" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml deleted file mode 100644 index f46305b517..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml +++ /dev/null @@ -1,44 +0,0 @@ -{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.verticalPodAutoscaler.enabled) }} -apiVersion: autoscaling.k8s.io/v1 -kind: VerticalPodAutoscaler -metadata: - name: {{ template "kube-state-metrics.fullname" . }} - namespace: {{ template "kube-state-metrics.namespace" . }} - labels: - {{- include "kube-state-metrics.labels" . | indent 4 }} -spec: - {{- with .Values.verticalPodAutoscaler.recommenders }} - recommenders: - {{- toYaml . | nindent 4 }} - {{- end }} - resourcePolicy: - containerPolicies: - - containerName: {{ template "kube-state-metrics.name" . }} - {{- with .Values.verticalPodAutoscaler.controlledResources }} - controlledResources: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- if .Values.verticalPodAutoscaler.controlledValues }} - controlledValues: {{ .Values.verticalPodAutoscaler.controlledValues }} - {{- end }} - {{- if .Values.verticalPodAutoscaler.maxAllowed }} - maxAllowed: - {{ toYaml .Values.verticalPodAutoscaler.maxAllowed | nindent 8 }} - {{- end }} - {{- if .Values.verticalPodAutoscaler.minAllowed }} - minAllowed: - {{ toYaml .Values.verticalPodAutoscaler.minAllowed | nindent 8 }} - {{- end }} - targetRef: - apiVersion: apps/v1 - {{- if .Values.autosharding.enabled }} - kind: StatefulSet - {{- else }} - kind: Deployment - {{- end }} - name: {{ template "kube-state-metrics.fullname" . }} - {{- with .Values.verticalPodAutoscaler.updatePolicy }} - updatePolicy: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/values.yaml deleted file mode 100644 index ab111f8091..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kube-state-metrics/values.yaml +++ /dev/null @@ -1,523 +0,0 @@ -# Default values for kube-state-metrics. -prometheusScrape: true -image: - registry: docker.io - repository: rancher/mirrored-kube-state-metrics-kube-state-metrics - tag: v2.12.0 - sha: "" - pullPolicy: IfNotPresent - -imagePullSecrets: [] -# - name: "image-pull-secret" - -global: - cattle: - systemDefaultRegistry: "" - - # To help compatibility with other charts which use global.imagePullSecrets. - # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). - # global: - # imagePullSecrets: - # - name: pullSecret1 - # - name: pullSecret2 - # or - # global: - # imagePullSecrets: - # - pullSecret1 - # - pullSecret2 - imagePullSecrets: [] - # - # Allow parent charts to override registry hostname - imageRegistry: "" - -# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data -# will be automatically sharded across <.Values.replicas> pods using the built-in -# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding -# This is an experimental feature and there are no stability guarantees. -autosharding: - enabled: false - -replicas: 1 - -# Change the deployment strategy when autosharding is disabled. -# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy -# The default is "RollingUpdate" as per Kubernetes defaults. -# During a release, 'RollingUpdate' can lead to two running instances for a short period of time while 'Recreate' can create a small gap in data. -# updateStrategy: Recreate - -# Number of old history to retain to allow rollback -# Default Kubernetes value is set to 10 -revisionHistoryLimit: 10 - -# List of additional cli arguments to configure kube-state-metrics -# for example: --enable-gzip-encoding, --log-file, etc. -# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md -extraArgs: [] - -# If false then the user will opt out of automounting API credentials. -automountServiceAccountToken: true - -service: - port: 8080 - # Default to clusterIP for backward compatibility - type: ClusterIP - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - nodePort: 0 - loadBalancerIP: "" - # Only allow access to the loadBalancerIP from these IPs - loadBalancerSourceRanges: [] - clusterIP: "" - annotations: {} - -## Additional labels to add to all resources -customLabels: {} - # app: kube-state-metrics - -## Override selector labels -selectorOverride: {} - -## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box -releaseLabel: false - -hostNetwork: false - -rbac: - # If true, create & use RBAC resources - create: true - - # Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here. - # useExistingRole: your-existing-role - - # If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to) - useClusterRole: true - - # Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration - # Example: - # - apiGroups: ["monitoring.coreos.com"] - # resources: ["prometheuses"] - # verbs: ["list", "watch"] - extraRules: [] - -# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled). -# The requests are served through the same service but requests are then HTTPS. -kubeRBACProxy: - enabled: false - image: - repository: rancher/mirrored-brancz-kube-rbac-proxy - tag: v0.18.0 - sha: "" - pullPolicy: IfNotPresent - - # List of additional cli arguments to configure kube-rbac-prxy - # for example: --tls-cipher-suites, --log-file, etc. - # all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage - extraArgs: [] - - ## Specify security settings for a Container - ## Allows overrides and additional options compared to (Pod) securityContext - ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container - containerSecurityContext: - readOnlyRootFilesystem: true - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - - 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: 64Mi - # requests: - # cpu: 10m - # memory: 32Mi - - ## volumeMounts enables mounting custom volumes in rbac-proxy containers - ## Useful for TLS certificates and keys - volumeMounts: [] - # - mountPath: /etc/tls - # name: kube-rbac-proxy-tls - # readOnly: true - -serviceAccount: - # Specifies whether a ServiceAccount should be created, require rbac true - 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: - # Reference to one or more secrets to be used when pulling images - # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - imagePullSecrets: [] - # ServiceAccount annotations. - # Use case: AWS EKS IAM roles for service accounts - # ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html - annotations: {} - # If false then the user will opt out of automounting API credentials. - automountServiceAccountToken: true - -prometheus: - monitor: - enabled: false - annotations: {} - additionalLabels: {} - namespace: "" - namespaceSelector: [] - jobLabel: "" - targetLabels: [] - podTargetLabels: [] - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - selectorOverride: {} - - ## kube-state-metrics endpoint - http: - interval: "" - scrapeTimeout: "" - proxyUrl: "" - ## Whether to enable HTTP2 for servicemonitor - enableHttp2: false - honorLabels: false - metricRelabelings: [] - relabelings: [] - scheme: "" - ## File to read bearer token for scraping targets - bearerTokenFile: "" - ## Secret to mount to read bearer token for scraping targets. The secret needs - ## to be in the same namespace as the service monitor and accessible by the - ## Prometheus Operator - bearerTokenSecret: {} - # name: secret-name - # key: key-name - tlsConfig: {} - - ## selfMonitor endpoint - metrics: - interval: "" - scrapeTimeout: "" - proxyUrl: "" - ## Whether to enable HTTP2 for servicemonitor - enableHttp2: false - honorLabels: false - metricRelabelings: [] - relabelings: [] - scheme: "" - ## File to read bearer token for scraping targets - bearerTokenFile: "" - ## Secret to mount to read bearer token for scraping targets. The secret needs - ## to be in the same namespace as the service monitor and accessible by the - ## Prometheus Operator - bearerTokenSecret: {} - # name: secret-name - # key: key-name - tlsConfig: {} - -## Specify if a Pod Security Policy for kube-state-metrics must be created -## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ -## -podSecurityPolicy: - enabled: false - annotations: {} - ## Specify pod annotations - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl - ## - # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' - # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' - # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' - - additionalVolumes: [] - -## Configure network policy for kube-state-metrics -networkPolicy: - enabled: false - # networkPolicy.flavor -- Flavor of the network policy to use. - # Can be: - # * kubernetes for networking.k8s.io/v1/NetworkPolicy - # * cilium for cilium.io/v2/CiliumNetworkPolicy - flavor: kubernetes - - ## Configure the cilium network policy kube-apiserver selector - # cilium: - # kubeApiServerSelector: - # - toEntities: - # - kube-apiserver - - # egress: - # - {} - # ingress: - # - {} - # podSelector: - # matchLabels: - # app.kubernetes.io/name: kube-state-metrics - -securityContext: - enabled: true - runAsGroup: 65534 - runAsUser: 65534 - fsGroup: 65534 - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - -## Specify security settings for a Container -## Allows overrides and additional options compared to (Pod) securityContext -## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container -containerSecurityContext: - readOnlyRootFilesystem: true - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - -## Node labels for pod assignment -## Ref: https://kubernetes.io/docs/user-guide/node-selection/ -nodeSelector: {} - -## Affinity settings for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ -affinity: {} - -## Tolerations for pod assignment -## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ -tolerations: [] - -## Topology spread constraints for pod assignment -## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ -topologySpreadConstraints: [] - -# Annotations to be added to the deployment/statefulset -annotations: {} - -# Annotations to be added to the pod -podAnnotations: {} - -## Assign a PriorityClassName to pods if set -# priorityClassName: "" - -# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ -podDisruptionBudget: {} - -# Comma-separated list of metrics to be exposed. -# This list comprises of exact metric names and/or regex patterns. -# The allowlist and denylist are mutually exclusive. -metricAllowlist: [] - -# Comma-separated list of metrics not to be enabled. -# This list comprises of exact metric names and/or regex patterns. -# The allowlist and denylist are mutually exclusive. -metricDenylist: [] - -# Comma-separated list of additional Kubernetes label keys that will be used in the resource's -# labels metric. By default the metric contains only name and namespace labels. -# To include additional labels, provide a list of resource names in their plural form and Kubernetes -# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. -# A single '*' can be provided per resource instead to allow any labels, but that has -# severe performance implications (Example: '=pods=[*]'). -metricLabelsAllowlist: [] - # - namespaces=[k8s-label-1,k8s-label-n] - -# Comma-separated list of Kubernetes annotations keys that will be used in the resource' -# labels metric. By default the metric contains only name and namespace labels. -# To include additional annotations provide a list of resource names in their plural form and Kubernetes -# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. -# A single '*' can be provided per resource instead to allow any annotations, but that has -# severe performance implications (Example: '=pods=[*]'). -metricAnnotationsAllowList: [] - # - pods=[k8s-annotation-1,k8s-annotation-n] - -# Available collectors for kube-state-metrics. -# By default, all available resources are enabled, comment out to disable. -collectors: - - certificatesigningrequests - - configmaps - - cronjobs - - daemonsets - - deployments - - endpoints - - horizontalpodautoscalers - - ingresses - - jobs - - leases - - limitranges - - mutatingwebhookconfigurations - - namespaces - - networkpolicies - - nodes - - persistentvolumeclaims - - persistentvolumes - - poddisruptionbudgets - - pods - - replicasets - - replicationcontrollers - - resourcequotas - - secrets - - services - - statefulsets - - storageclasses - - validatingwebhookconfigurations - - volumeattachments - -# Enabling kubeconfig will pass the --kubeconfig argument to the container -kubeconfig: - enabled: false - # base64 encoded kube-config file - secret: - -# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics -customResourceState: - enabled: false - # Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules - config: {} - -# Enable only the release namespace for collecting resources. By default all namespaces are collected. -# If releaseNamespace and namespaces are both set a merged list will be collected. -releaseNamespace: false - -# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected. -namespaces: "" - -# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, -# only namespaces that are excluded in namespaces-denylist will be used. -namespacesDenylist: "" - -## Override the deployment namespace -## -namespaceOverride: "" - -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: 64Mi - # requests: - # cpu: 10m - # memory: 32Mi - -## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role. -## For example: kubeTargetVersionOverride: 1.14.9 -## -kubeTargetVersionOverride: "" - -# Enable self metrics configuration for service and Service Monitor -# Default values for telemetry configuration can be overridden -# If you set telemetryNodePort, you must also set service.type to NodePort -selfMonitor: - enabled: false - # telemetryHost: 0.0.0.0 - # telemetryPort: 8081 - # telemetryNodePort: 0 - -# Enable vertical pod autoscaler support for kube-state-metrics -verticalPodAutoscaler: - enabled: false - - # Recommender 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: [] - # - name: custom-recommender-performance - - # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory - controlledResources: [] - # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. - # controlledValues: RequestsAndLimits - - # Define the max allowed resources for the pod - maxAllowed: {} - # cpu: 200m - # memory: 100Mi - # Define the min allowed resources for the pod - minAllowed: {} - # cpu: 200m - # memory: 100Mi - - # 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 - -# volumeMounts are used to add custom volume mounts to deployment. -# See example below -volumeMounts: [] -# - mountPath: /etc/config -# name: config-volume - -# volumes are used to add custom volumes to deployment -# See example below -volumes: [] -# - configMap: -# name: cm-for-volume -# name: config-volume - -# Extra manifests to deploy as an array -extraManifests: [] - # - apiVersion: v1 - # kind: ConfigMap - # metadata: - # labels: - # name: prometheus-extra - # data: - # extra-data: "value" - -## Containers allows injecting additional containers. -containers: [] - # - name: crd-init - # image: kiwigrid/k8s-sidecar:latest - -## InitContainers allows injecting additional initContainers. -initContainers: [] - # - name: crd-sidecar - # image: kiwigrid/k8s-sidecar:latest - -## Liveness probe -## -livenessProbe: - failureThreshold: 3 - httpGet: - httpHeaders: [] - scheme: http - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 5 - -## Readiness probe -## -readinessProbe: - failureThreshold: 3 - httpGet: - httpHeaders: [] - scheme: http - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 5 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/Chart.yaml deleted file mode 100644 index 2c7102aeaa..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: kubeAdmControllerManager -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmControllerManager/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/Chart.yaml deleted file mode 100644 index 5e21f46dd9..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: kubeAdmEtcd -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmEtcd/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/Chart.yaml deleted file mode 100644 index 5ec8f95231..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: kubeAdmProxy -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmProxy/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/Chart.yaml deleted file mode 100644 index 0d8a9da226..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: kubeAdmScheduler -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/kubeAdmScheduler/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/.helmignore deleted file mode 100644 index f0c1319444..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/.helmignore +++ /dev/null @@ -1,21 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/Chart.yaml deleted file mode 100644 index bed274d82c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/Chart.yaml +++ /dev/null @@ -1,27 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-prometheus-adapter -apiVersion: v1 -appVersion: v0.11.2 -description: A Helm chart for k8s prometheus adapter -home: https://github.com/kubernetes-sigs/prometheus-adapter -keywords: -- hpa -- metrics -- prometheus -- adapter -maintainers: -- email: mattias.gees@jetstack.io - name: mattiasgees -- name: steven-sheehy -- email: hfernandez@mesosphere.com - name: hectorj2f -name: prometheus-adapter -sources: -- https://github.com/kubernetes/charts -- https://github.com/kubernetes-sigs/prometheus-adapter -version: 4.10.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/README.md deleted file mode 100644 index d77bb0c920..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/README.md +++ /dev/null @@ -1,160 +0,0 @@ -# Prometheus Adapter - -Installs the [Prometheus Adapter](https://github.com/kubernetes-sigs/prometheus-adapter) for the Custom Metrics API. Custom metrics are used in Kubernetes by [Horizontal Pod Autoscalers](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) to scale workloads based upon your own metric pulled from an external metrics provider like Prometheus. This chart complements the [metrics-server](https://github.com/helm/charts/tree/master/stable/metrics-server) chart that provides resource only metrics. - -## Prerequisites - -Kubernetes 1.14+ - -## Get Helm Repositories Info - -```console -helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -helm repo update -``` - -_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ - -## Install Helm Chart - -```console -helm install [RELEASE_NAME] prometheus-community/prometheus-adapter -``` - -_See [configuration](#configuration) below._ - -_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ - -## 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._ - -## Upgrading Helm Chart - -```console -helm upgrade [RELEASE_NAME] [CHART] --install -``` - -_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ - -### To 4.2.0 - -Readiness and liveness probes are now fully configurable through values `readinessProbe` and `livenessProbe`. The previous values have been kept as defaults. - -### To 4.0.0 - -Previously, security context of the container was set directly in the deployment template. This release makes it configurable through the new configuration variable `securityContext` whilst keeping the previously set values as defaults. Furthermore, previous variable `runAsUser` is now set in `securityContext` and is not used any longer. Please, use `securityContext.runAsUser` instead. In the same security context, `seccompProfile` has been enabled and set to type `RuntimeDefault`. - -### To 3.0.0 - -Due to a change in deployment labels, the upgrade requires `helm upgrade --force` in order to re-create the deployment. - -## Configuration - -See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: - -```console -helm show values prometheus-community/prometheus-adapter -``` - -### Prometheus Service Endpoint - -To use the chart, ensure the `prometheus.url` and `prometheus.port` are configured with the correct Prometheus service endpoint. If Prometheus is exposed under HTTPS the host's CA Bundle must be exposed to the container using `extraVolumes` and `extraVolumeMounts`. - -### Adapter Rules - -Additionally, the chart comes with a set of default rules out of the box but they may pull in too many metrics or not map them correctly for your needs. Therefore, it is recommended to populate `rules.custom` with a list of rules (see the [config document](https://github.com/kubernetes-sigs/prometheus-adapter/blob/master/docs/config.md) for the proper format). - -### Horizontal Pod Autoscaler Metrics - -Finally, to configure your Horizontal Pod Autoscaler to use the custom metric, see the custom metrics section of the [HPA walkthrough](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics). - -The Prometheus Adapter can serve three different [metrics APIs](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis): - -### Custom Metrics - -Enabling this option will cause custom metrics to be served at `/apis/custom.metrics.k8s.io/v1beta1`. Enabled by default when `rules.default` is true, but can be customized by populating `rules.custom`: - -```yaml -rules: - custom: - - seriesQuery: '{__name__=~"^some_metric_count$"}' - resources: - template: <<.Resource>> - name: - matches: "" - as: "my_custom_metric" - metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) -``` - -### External Metrics - -Enabling this option will cause external metrics to be served at `/apis/external.metrics.k8s.io/v1beta1`. Can be enabled by populating `rules.external`: - -```yaml -rules: - external: - - seriesQuery: '{__name__=~"^some_metric_count$"}' - resources: - template: <<.Resource>> - name: - matches: "" - as: "my_external_metric" - metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) -``` - -### Resource Metrics - -Enabling this option will cause resource metrics to be served at `/apis/metrics.k8s.io/v1beta1`. Resource metrics will allow pod CPU and Memory metrics to be used in [Horizontal Pod Autoscalers](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) as well as the `kubectl top` command. Can be enabled by populating `rules.resource`: - -```yaml -rules: - resource: - cpu: - containerQuery: | - sum by (<<.GroupBy>>) ( - rate(container_cpu_usage_seconds_total{container!="",<<.LabelMatchers>>}[3m]) - ) - nodeQuery: | - sum by (<<.GroupBy>>) ( - rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal",<<.LabelMatchers>>}[3m]) - ) - resources: - overrides: - node: - resource: node - namespace: - resource: namespace - pod: - resource: pod - containerLabel: container - memory: - containerQuery: | - sum by (<<.GroupBy>>) ( - avg_over_time(container_memory_working_set_bytes{container!="",<<.LabelMatchers>>}[3m]) - ) - nodeQuery: | - sum by (<<.GroupBy>>) ( - avg_over_time(node_memory_MemTotal_bytes{<<.LabelMatchers>>}[3m]) - - - avg_over_time(node_memory_MemAvailable_bytes{<<.LabelMatchers>>}[3m]) - ) - resources: - overrides: - node: - resource: node - namespace: - resource: namespace - pod: - resource: pod - containerLabel: container - window: 3m -``` - -**NOTE:** Setting a value for `rules.resource` will also deploy the resource metrics API service, providing the same functionality as [metrics-server](https://github.com/helm/charts/tree/master/stable/metrics-server). As such it is not possible to deploy them both in the same cluster. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/NOTES.txt deleted file mode 100644 index b7b9b99322..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/NOTES.txt +++ /dev/null @@ -1,9 +0,0 @@ -{{ template "k8s-prometheus-adapter.fullname" . }} has been deployed. -In a few minutes you should be able to list metrics using the following command(s): -{{ if .Values.rules.resource }} - kubectl get --raw /apis/metrics.k8s.io/v1beta1 -{{- end }} - kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 -{{ if .Values.rules.external }} - kubectl get --raw /apis/external.metrics.k8s.io/v1beta1 -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/_helpers.tpl deleted file mode 100644 index edbb829b2b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/_helpers.tpl +++ /dev/null @@ -1,113 +0,0 @@ -# Rancher -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "k8s-prometheus-adapter.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 "k8s-prometheus-adapter.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 -}} - -{{/* -Allow the release namespace to be overridden for multi-namespace deployments in combined charts -*/}} -{{- define "k8s-prometheus-adapter.namespace" -}} -{{- default .Release.Namespace .Values.namespaceOverride -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "k8s-prometheus-adapter.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Generate basic labels -*/}} -{{- define "k8s-prometheus-adapter.labels" }} -helm.sh/chart: {{ include "k8s-prometheus-adapter.chart" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -app.kubernetes.io/component: metrics -app.kubernetes.io/part-of: {{ template "k8s-prometheus-adapter.name" . }} -{{- include "k8s-prometheus-adapter.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -{{- if .Values.customLabels }} -{{ toYaml .Values.customLabels }} -{{- end }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "k8s-prometheus-adapter.selectorLabels" }} -app.kubernetes.io/name: {{ include "k8s-prometheus-adapter.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "k8s-prometheus-adapter.serviceAccountName" -}} -{{- if .Values.serviceAccount.create -}} - {{ default (include "k8s-prometheus-adapter.fullname" .) .Values.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* Get Policy API Version */}} -{{- define "k8s-prometheus-adapter.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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/certmanager.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/certmanager.yaml deleted file mode 100644 index 4e32c964c6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/certmanager.yaml +++ /dev/null @@ -1,76 +0,0 @@ -{{- if .Values.certManager.enabled -}} ---- -# Create a selfsigned Issuer, in order to create a root CA certificate for -# signing webhook serving certificates -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: {{ template "k8s-prometheus-adapter.fullname" . }}-self-signed-issuer - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} -spec: - selfSigned: {} ---- -# Generate a CA Certificate used to sign certificates for the webhook -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: {{ template "k8s-prometheus-adapter.fullname" . }}-root-cert - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} -spec: - secretName: {{ template "k8s-prometheus-adapter.fullname" . }}-root-cert - duration: {{ .Values.certManager.caCertDuration }} - issuerRef: - name: {{ template "k8s-prometheus-adapter.fullname" . }}-self-signed-issuer - commonName: "ca.webhook.prometheus-adapter" - isCA: true ---- -# Create an Issuer that uses the above generated CA certificate to issue certs -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: {{ template "k8s-prometheus-adapter.fullname" . }}-root-issuer - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} -spec: - ca: - secretName: {{ template "k8s-prometheus-adapter.fullname" . }}-root-cert ---- -# Finally, generate a serving certificate for the apiservices to use -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: {{ template "k8s-prometheus-adapter.fullname" . }}-cert - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} -spec: - secretName: {{ template "k8s-prometheus-adapter.fullname" . }} - duration: {{ .Values.certManager.certDuration }} - issuerRef: - name: {{ template "k8s-prometheus-adapter.fullname" . }}-root-issuer - dnsNames: - - {{ template "k8s-prometheus-adapter.fullname" . }} - - {{ template "k8s-prometheus-adapter.fullname" . }}.{{ include "k8s-prometheus-adapter.namespace" . }} - - {{ template "k8s-prometheus-adapter.fullname" . }}.{{ include "k8s-prometheus-adapter.namespace" . }}.svc -{{- end -}} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml deleted file mode 100644 index 6701e6ba08..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-system-auth-delegator -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: system:auth-delegator -subjects: -- kind: ServiceAccount - name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-reader.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-reader.yaml deleted file mode 100644 index fe13048847..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-reader.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.rbac.create .Values.rbac.useAuthReaderClusterRole -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-auth-reader -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: extension-apiserver-authentication-reader -subjects: -- kind: ServiceAccount - name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml deleted file mode 100644 index 67efd2aa2f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-resource-reader -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "k8s-prometheus-adapter.name" . }}-resource-reader -subjects: -- kind: ServiceAccount - name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml deleted file mode 100644 index 2c690a03cc..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-resource-reader -rules: -- apiGroups: - - "" - resources: - - namespaces - - pods - - services - - configmaps - verbs: - - get - - list - - watch -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/configmap.yaml deleted file mode 100644 index 17f415d970..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/configmap.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- if not .Values.rules.existing -}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "k8s-prometheus-adapter.fullname" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} -data: - config.yaml: | -{{- if or .Values.rules.default .Values.rules.custom }} - rules: -{{- if .Values.rules.default }} - - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' - seriesFilters: [] - resources: - overrides: - namespace: - resource: namespace - pod: - resource: pod - name: - matches: ^container_(.*)_seconds_total$ - as: "" - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[5m])) - by (<<.GroupBy>>) - - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' - seriesFilters: - - isNot: ^container_.*_seconds_total$ - resources: - overrides: - namespace: - resource: namespace - pod: - resource: pod - name: - matches: ^container_(.*)_total$ - as: "" - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[5m])) - by (<<.GroupBy>>) - - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' - seriesFilters: - - isNot: ^container_.*_total$ - resources: - overrides: - namespace: - resource: namespace - pod: - resource: pod - name: - matches: ^container_(.*)$ - as: "" - metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>,container!="POD"}) by (<<.GroupBy>>) - - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' - seriesFilters: - - isNot: .*_total$ - resources: - template: <<.Resource>> - name: - matches: "" - as: "" - metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) - - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' - seriesFilters: - - isNot: .*_seconds_total - resources: - template: <<.Resource>> - name: - matches: ^(.*)_total$ - as: "" - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>) - - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' - seriesFilters: [] - resources: - template: <<.Resource>> - name: - matches: ^(.*)_seconds_total$ - as: "" - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>) -{{- end -}} -{{- if .Values.rules.custom }} -{{ toYaml .Values.rules.custom | indent 4 }} -{{- end -}} -{{- end -}} -{{- if .Values.rules.external }} - externalRules: -{{ toYaml .Values.rules.external | indent 4 }} -{{- end -}} -{{- if .Values.rules.resource }} - resourceRules: -{{ toYaml .Values.rules.resource | indent 6 }} -{{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml deleted file mode 100644 index 8b7b4e555e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if or .Values.rules.default .Values.rules.custom }} -{{- if .Capabilities.APIVersions.Has "apiregistration.k8s.io/v1" }} -apiVersion: apiregistration.k8s.io/v1 -{{- else }} -apiVersion: apiregistration.k8s.io/v1beta1 -{{- end }} -kind: APIService -metadata: -{{- if or .Values.certManager.enabled .Values.customAnnotations }} - annotations: - certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} - cert-manager.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} - {{- if .Values.customAnnotations }} - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} -{{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: v1beta1.custom.metrics.k8s.io -spec: - service: - name: {{ template "k8s-prometheus-adapter.fullname" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} - {{- if .Values.tls.enable }} - caBundle: {{ b64enc .Values.tls.ca }} - {{- end }} - group: custom.metrics.k8s.io - version: v1beta1 - {{- if not (or .Values.tls.enable .Values.certManager.enabled) }} - insecureSkipTLSVerify: true - {{- end }} - groupPriorityMinimum: 100 - versionPriority: 100 -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml deleted file mode 100644 index 0cc6920836..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- /* -This if must be aligned with custom-metrics-cluster-role.yaml -as otherwise this binding will point to not existing role. -*/ -}} -{{- if and .Values.rbac.create (or .Values.rules.default .Values.rules.custom) -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-hpa-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "k8s-prometheus-adapter.name" . }}-server-resources -subjects: -- kind: ServiceAccount - name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml deleted file mode 100644 index f441e1bdb6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.rbac.create (or .Values.rules.default .Values.rules.custom) -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-server-resources -rules: -- apiGroups: - - custom.metrics.k8s.io - resources: {{ toYaml .Values.rbac.customMetrics.resources | nindent 2 }} - verbs: ["*"] -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/deployment.yaml deleted file mode 100644 index 03267b5e3b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/deployment.yaml +++ /dev/null @@ -1,151 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - {{- if or .Values.customAnnotations .Values.deploymentAnnotations }} - annotations: - {{- with .Values.customAnnotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.deploymentAnnotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.fullname" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} -spec: - replicas: {{ .Values.replicas }} - strategy: {{ toYaml .Values.strategy | nindent 4 }} - selector: - matchLabels: - {{- include "k8s-prometheus-adapter.selectorLabels" . | indent 6 }} - template: - metadata: - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 8 }} - {{- with .Values.podLabels }} - {{- toYaml . | trim | nindent 8 }} - {{- end }} - name: {{ template "k8s-prometheus-adapter.name" . }} - annotations: - checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} - {{- with .Values.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.customAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - {{- if .Values.hostNetwork.enabled }} - hostNetwork: true - {{- end }} - {{- if .Values.dnsPolicy }} - dnsPolicy: {{ .Values.dnsPolicy }} - {{- end}} - {{- with .Values.dnsConfig }} - dnsConfig: - {{- toYaml . | nindent 8 }} - {{- end }} - containers: - - name: {{ .Chart.Name }} - image: "{{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - {{- with .Values.env }} - env: - {{- toYaml . | nindent 8 }} - {{- end }} - args: - - /adapter - - --secure-port={{ .Values.listenPort }} - {{- if or .Values.tls.enable .Values.certManager.enabled }} - - --tls-cert-file=/var/run/serving-cert/tls.crt - - --tls-private-key-file=/var/run/serving-cert/tls.key - {{- end }} - - --cert-dir=/tmp/cert - - --prometheus-url={{ tpl .Values.prometheus.url . }}{{ if .Values.prometheus.port }}:{{ .Values.prometheus.port }}{{end}}{{ .Values.prometheus.path }} - - --metrics-relist-interval={{ .Values.metricsRelistInterval }} - - --v={{ .Values.logLevel }} - - --config=/etc/adapter/config.yaml - {{- if .Values.extraArguments }} - {{- toYaml .Values.extraArguments | trim | nindent 8 }} - {{- end }} - ports: - - containerPort: {{ .Values.listenPort }} - name: https - {{- with .Values.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 10 }} - {{- end }} - {{- with .Values.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 10 }} - {{- end }} - {{- with .Values.startupProbe }} - startupProbe: - {{- toYaml . | nindent 10 }} - {{- end }} - {{- if .Values.resources }} - resources: - {{- toYaml .Values.resources | nindent 10 }} - {{- end }} - {{- with .Values.securityContext }} - securityContext: - {{- toYaml . | nindent 10 }} - {{- end }} - volumeMounts: - {{- if .Values.extraVolumeMounts }} - {{ toYaml .Values.extraVolumeMounts | trim | nindent 8 }} - {{ end }} - - mountPath: /etc/adapter/ - name: config - readOnly: true - - mountPath: /tmp - name: tmp - {{- if or .Values.tls.enable .Values.certManager.enabled }} - - mountPath: /var/run/serving-cert - name: volume-serving-cert - readOnly: true - {{- end }} - {{- with .Values.extraContainers }} - {{- toYaml . | nindent 6 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} - nodeSelector: - {{- toYaml .Values.nodeSelector | nindent 8 }} - affinity: - {{- toYaml .Values.affinity | nindent 8 }} - topologySpreadConstraints: - {{- toYaml .Values.topologySpreadConstraints | nindent 8 }} - {{- with .Values.priorityClassName }} - priorityClassName: {{ . }} - {{- end }} - {{- if .Values.podSecurityContext }} - securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} - {{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.tolerations }} -{{- toYaml .Values.tolerations | nindent 8 }} -{{- end }} - {{- if .Values.image.pullSecrets }} - imagePullSecrets: - {{- range .Values.image.pullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - volumes: - {{- if .Values.extraVolumes }} - {{ toYaml .Values.extraVolumes | trim | nindent 6 }} - {{ end }} - - name: config - configMap: - name: {{ .Values.rules.existing | default (include "k8s-prometheus-adapter.fullname" . ) }} - - name: tmp - emptyDir: {} - {{- if or .Values.tls.enable .Values.certManager.enabled }} - - name: volume-serving-cert - secret: - secretName: {{ template "k8s-prometheus-adapter.fullname" . }} - {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml deleted file mode 100644 index 21339af128..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.rules.external }} -{{- if .Capabilities.APIVersions.Has "apiregistration.k8s.io/v1" }} -apiVersion: apiregistration.k8s.io/v1 -{{- else }} -apiVersion: apiregistration.k8s.io/v1beta1 -{{- end }} -kind: APIService -metadata: -{{- if or .Values.certManager.enabled .Values.customAnnotations }} - annotations: - certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} - cert-manager.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} - {{- if .Values.customAnnotations }} - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} -{{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: v1beta1.external.metrics.k8s.io -spec: - service: - name: {{ template "k8s-prometheus-adapter.fullname" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} - {{- if .Values.tls.enable }} - caBundle: {{ b64enc .Values.tls.ca }} - {{- end }} - group: external.metrics.k8s.io - version: v1beta1 - {{- if not (or .Values.tls.enable .Values.certManager.enabled) }} - insecureSkipTLSVerify: true - {{- end }} - groupPriorityMinimum: 100 - versionPriority: 100 -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml deleted file mode 100644 index 05547bd323..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.rbac.create .Values.rules.external -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-hpa-controller-external-metrics -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "k8s-prometheus-adapter.name" . }}-external-metrics -subjects: -- kind: ServiceAccount - name: horizontal-pod-autoscaler - namespace: kube-system -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml deleted file mode 100644 index 71783fd4b2..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.rbac.create .Values.rules.external -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-external-metrics -rules: -- apiGroups: - - "external.metrics.k8s.io" - resources: {{ toYaml .Values.rbac.externalMetrics.resources | nindent 2 }} - verbs: - - list - - get - - watch -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/pdb.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/pdb.yaml deleted file mode 100644 index 205761a9f1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/pdb.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if .Values.podDisruptionBudget.enabled }} -apiVersion: {{ include "k8s-prometheus-adapter.pdb.apiVersion" . }} -kind: PodDisruptionBudget -metadata: - name: {{ template "k8s-prometheus-adapter.fullname" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} -spec: - {{- if .Values.podDisruptionBudget.minAvailable }} - minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} - {{- end }} - {{- if .Values.podDisruptionBudget.maxUnavailable }} - maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} - {{- end }} - selector: - matchLabels: - {{- include "k8s-prometheus-adapter.selectorLabels" . | indent 6 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/psp.yaml deleted file mode 100644 index ec26af502c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/psp.yaml +++ /dev/null @@ -1,66 +0,0 @@ -{{- if and .Values.psp.create (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} ---- -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "k8s-prometheus-adapter.fullname" . }} - {{- with (merge .Values.customAnnotations .Values.psp.annotations) }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} -spec: - {{- if .Values.hostNetwork.enabled }} - hostNetwork: true - hostPorts: - - min: {{ .Values.listenPort }} - max: {{ .Values.listenPort }} - {{- end }} - fsGroup: - rule: RunAsAny - runAsGroup: - rule: RunAsAny - runAsUser: - rule: MustRunAs - ranges: - - min: 1024 - max: 65535 - seLinux: - rule: RunAsAny - supplementalGroups: - rule: RunAsAny - volumes: - - secret - - emptyDir - - configMap ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-psp -rules: -- apiGroups: - - 'policy' - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "k8s-prometheus-adapter.fullname" . }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-psp -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "k8s-prometheus-adapter.name" . }}-psp -subjects: -- kind: ServiceAccount - name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml deleted file mode 100644 index 0cc9fff6a2..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.rules.resource}} -{{- if .Capabilities.APIVersions.Has "apiregistration.k8s.io/v1" }} -apiVersion: apiregistration.k8s.io/v1 -{{- else }} -apiVersion: apiregistration.k8s.io/v1beta1 -{{- end }} -kind: APIService -metadata: -{{- if or .Values.certManager.enabled .Values.customAnnotations }} - annotations: - certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} - cert-manager.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} - {{- if .Values.customAnnotations }} - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} -{{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: v1beta1.metrics.k8s.io -spec: - service: - name: {{ template "k8s-prometheus-adapter.fullname" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} - {{- if .Values.tls.enable }} - caBundle: {{ b64enc .Values.tls.ca }} - {{- end }} - group: metrics.k8s.io - version: v1beta1 - {{- if not (or .Values.tls.enable .Values.certManager.enabled) }} - insecureSkipTLSVerify: true - {{- end }} - groupPriorityMinimum: 100 - versionPriority: 100 -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml deleted file mode 100644 index 3c247e48d2..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.rbac.create .Values.rules.resource -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-hpa-controller-metrics -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "k8s-prometheus-adapter.name" . }}-metrics -subjects: -- kind: ServiceAccount - name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml deleted file mode 100644 index 73d8953046..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if and .Values.rbac.create .Values.rules.resource -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-metrics -rules: -- apiGroups: - - "" - resources: - - pods - - nodes - - nodes/stats - verbs: - - get - - list - - watch -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml deleted file mode 100644 index f01997e62d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.rbac.create (not .Values.rbac.useAuthReaderClusterRole) -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.name" . }}-auth-reader - namespace: kube-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: extension-apiserver-authentication-reader -subjects: -- kind: ServiceAccount - name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/secret.yaml deleted file mode 100644 index 3e7e8887bd..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/secret.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.tls.enable -}} -apiVersion: v1 -kind: Secret -metadata: - {{- if .Values.customAnnotations }} - annotations: - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.fullname" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} -type: kubernetes.io/tls -data: - tls.crt: {{ b64enc .Values.tls.certificate }} - tls.key: {{ b64enc .Values.tls.key }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/service.yaml deleted file mode 100644 index 4879385ebc..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/service.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - {{- if or .Values.service.annotations .Values.customAnnotations }} - annotations: - {{- if .Values.service.annotations }} - {{ toYaml .Values.service.annotations | indent 4 }} - {{- end }} - {{- if .Values.customAnnotations }} - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} - {{- end }} - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.fullname" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} -spec: -{{- if .Values.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} -{{- end }} - ports: - - port: {{ .Values.service.port }} - name: https - protocol: TCP - targetPort: https - selector: - {{- include "k8s-prometheus-adapter.selectorLabels" . | indent 4 }} - type: {{ .Values.service.type }} - {{- if .Values.service.clusterIP }} - clusterIP: {{ .Values.service.clusterIP }} - {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/serviceaccount.yaml deleted file mode 100644 index 30a169ae0e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/templates/serviceaccount.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} - name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} - namespace: {{ include "k8s-prometheus-adapter.namespace" . }} -{{- if or .Values.serviceAccount.annotations .Values.customAnnotations }} - annotations: - {{- if .Values.serviceAccount.annotations }} - {{- toYaml .Values.serviceAccount.annotations | nindent 4 }} - {{- end }} - {{- if .Values.customAnnotations }} - {{- toYaml .Values.customAnnotations | nindent 4 }} - {{- end }} -{{- end }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/values.yaml deleted file mode 100644 index e3eeb388a0..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-adapter/values.yaml +++ /dev/null @@ -1,292 +0,0 @@ -affinity: {} - -topologySpreadConstraints: [] - -image: - repository: rancher/mirrored-prometheus-adapter-prometheus-adapter - # if not set appVersion field from Chart.yaml is used - tag: v0.12.0 - pullPolicy: IfNotPresent - -logLevel: 4 - -metricsRelistInterval: 1m - -listenPort: 6443 - -nodeSelector: {} - -priorityClassName: "" - -## Override the release namespace (for multi-namespace deployments in combined charts) -namespaceOverride: "" - -## Additional annotations to add to all resources -customAnnotations: {} - # role: custom-metrics - -## Additional labels to add to all resources -customLabels: {} - # monitoring: prometheus-adapter - -# Url to access prometheus -prometheus: - # Value is templated - url: http://prometheus.default.svc - port: 9090 - path: "" - -replicas: 1 - -# k8s 1.21 needs fsGroup to be set for non root deployments -# ref: https://github.com/kubernetes/kubernetes/issues/70679 -podSecurityContext: - fsGroup: 10001 - -# SecurityContext of the container -# ref. https://kubernetes.io/docs/tasks/configure-pod-container/security-context -securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 10001 - seccompProfile: - type: RuntimeDefault - -rbac: - # Specifies whether RBAC resources should be created - create: true - # Specifies if a Cluster Role should be used for the Auth Reader - useAuthReaderClusterRole: false - externalMetrics: - resources: ["*"] - customMetrics: - resources: ["*"] - -psp: - # Specifies whether PSP resources should be created - create: false - # Annotations added to the pod security policy - annotations: {} - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl - -serviceAccount: - # 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: - # ServiceAccount annotations. - # Use case: AWS EKS IAM roles for service accounts - # ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html - annotations: {} - -# Custom DNS configuration to be added to prometheus-adapter pods -dnsConfig: {} - # nameservers: - # - 1.2.3.4 - # searches: - # - ns1.svc.cluster-domain.example - # - my.dns.search.suffix - # options: - # - name: ndots - # value: "2" - # - name: edns0 - -resources: {} - # requests: - # cpu: 100m - # memory: 128Mi - # limits: - # cpu: 100m - # memory: 128Mi - -# Configure liveness probe -# https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#Probe -livenessProbe: - httpGet: - path: /healthz - port: https - scheme: HTTPS - initialDelaySeconds: 30 - timeoutSeconds: 5 - -# Configure readiness probe -readinessProbe: - httpGet: - path: /healthz - port: https - scheme: HTTPS - initialDelaySeconds: 30 - timeoutSeconds: 5 - -# Configure startup probe -# Use if prometheus-adapter takes a long time to finish startup e.g. polling a lot of API versions in cluster -startupProbe: {} - -rules: - default: true - - custom: [] - # - seriesQuery: '{__name__=~"^some_metric_count$"}' - # resources: - # template: <<.Resource>> - # name: - # matches: "" - # as: "my_custom_metric" - # metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) - - # Mounts a configMap with pre-generated rules for use. Overrides the - # default, custom, external and resource entries - existing: - - external: [] - # - seriesQuery: '{__name__=~"^some_metric_count$"}' - # resources: - # template: <<.Resource>> - # name: - # matches: "" - # as: "my_external_metric" - # metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) - - # resource: - # cpu: - # containerQuery: | - # sum by (<<.GroupBy>>) ( - # rate(container_cpu_usage_seconds_total{container!="",<<.LabelMatchers>>}[3m]) - # ) - # nodeQuery: | - # sum by (<<.GroupBy>>) ( - # rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal",<<.LabelMatchers>>}[3m]) - # ) - # resources: - # overrides: - # node: - # resource: node - # namespace: - # resource: namespace - # pod: - # resource: pod - # containerLabel: container - # memory: - # containerQuery: | - # sum by (<<.GroupBy>>) ( - # avg_over_time(container_memory_working_set_bytes{container!="",<<.LabelMatchers>>}[3m]) - # ) - # nodeQuery: | - # sum by (<<.GroupBy>>) ( - # avg_over_time(node_memory_MemTotal_bytes{<<.LabelMatchers>>}[3m]) - # - - # avg_over_time(node_memory_MemAvailable_bytes{<<.LabelMatchers>>}[3m]) - # ) - # resources: - # overrides: - # node: - # resource: node - # namespace: - # resource: namespace - # pod: - # resource: pod - # containerLabel: container - # window: 3m - -service: - annotations: {} - port: 443 - type: ClusterIP - # clusterIP: 1.2.3.4 - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" -tls: - enable: false - ca: |- - # Public CA file that signed the APIService - key: |- - # Private key of the APIService - certificate: |- - # Public key of the APIService - -# Set environment variables from secrets, configmaps or by setting them as name/value -env: [] - # - name: TMP_DIR - # value: /tmp - # - name: PASSWORD - # valueFrom: - # secretKeyRef: - # name: mysecret - # key: password - # optional: false - -# Any extra arguments -extraArguments: [] - # - --tls-private-key-file=/etc/tls/tls.key - # - --tls-cert-file=/etc/tls/tls.crt - -# Additional containers to add to the pod -extraContainers: [] - -# Any extra volumes -extraVolumes: [] - # - name: example-name - # hostPath: - # path: /path/on/host - # type: DirectoryOrCreate - # - name: ssl-certs - # hostPath: - # path: /etc/ssl/certs/ca-bundle.crt - # type: File - -# Any extra volume mounts -extraVolumeMounts: [] - # - name: example-name - # mountPath: /path/in/container - # - name: ssl-certs - # mountPath: /etc/ssl/certs/ca-certificates.crt - # readOnly: true - -tolerations: [] - -# Labels added to the pod -podLabels: {} - -# Annotations added to the pod -podAnnotations: {} - -# Annotations added to the deployment -deploymentAnnotations: {} - -hostNetwork: - # Specifies if prometheus-adapter should be started in hostNetwork mode. - # - # You would require this enabled if you use alternate overlay networking for pods and - # API server unable to communicate with metrics-server. As an example, this is required - # if you use Weave network on EKS. See also dnsPolicy - enabled: false - -# When hostNetwork is enabled, you probably want to set this to ClusterFirstWithHostNet -# dnsPolicy: ClusterFirstWithHostNet - -# Deployment strategy type -strategy: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 25% - maxSurge: 25% - -podDisruptionBudget: - # Specifies if PodDisruptionBudget should be enabled - # When enabled, minAvailable or maxUnavailable should also be defined. - enabled: false - minAvailable: - maxUnavailable: 1 - -certManager: - enabled: false - caCertDuration: 43800h0m0s - certDuration: 8760h0m0s diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/.helmignore deleted file mode 100644 index f0c1319444..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/.helmignore +++ /dev/null @@ -1,21 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/Chart.yaml deleted file mode 100644 index 2afcc31034..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/Chart.yaml +++ /dev/null @@ -1,25 +0,0 @@ -annotations: - artifacthub.io/license: Apache-2.0 - artifacthub.io/links: | - - name: Chart Source - url: https://github.com/prometheus-community/helm-charts -apiVersion: v2 -appVersion: 1.8.2 -description: A Helm chart for prometheus node-exporter -home: https://github.com/prometheus/node_exporter/ -keywords: -- node-exporter -- prometheus -- exporter -maintainers: -- email: gianrubio@gmail.com - name: gianrubio -- email: zanhsieh@gmail.com - name: zanhsieh -- email: rootsandtrees@posteo.de - name: zeritti -name: prometheus-node-exporter -sources: -- https://github.com/prometheus/node_exporter/ -type: application -version: 4.37.1 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/README.md deleted file mode 100644 index ef83844102..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# Prometheus Node Exporter - -Prometheus exporter for hardware and OS metrics exposed by *NIX kernels, written in Go with pluggable metric collectors. - -This chart bootstraps a Prometheus [Node Exporter](http://github.com/prometheus/node_exporter) daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -## Get Repository Info - -```console -helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -helm repo update -``` - -_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ - -## Install Chart - -```console -helm install [RELEASE_NAME] prometheus-community/prometheus-node-exporter -``` - -_See [configuration](#configuring) below._ - -_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ - -## Uninstall 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._ - -## Upgrading Chart - -```console -helm upgrade [RELEASE_NAME] prometheus-community/prometheus-node-exporter --install -``` - -_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ - -### 3.x to 4.x - -Starting from version 4.0.0, the `node exporter` chart is using the [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/). Therefore you have to delete the daemonset before you upgrade. - -```console -kubectl delete daemonset -l app=prometheus-node-exporter -helm upgrade -i prometheus-node-exporter prometheus-community/prometheus-node-exporter -``` - -If you use your own custom [ServiceMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor) or [PodMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#podmonitor), please ensure to upgrade their `selector` fields accordingly to the new labels. - -### From 2.x to 3.x - -Change the following: - -```yaml -hostRootFsMount: true -``` - -to: - -```yaml -hostRootFsMount: - enabled: true - mountPropagation: HostToContainer -``` - -## Configuring - -See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: - -```console -helm show values prometheus-community/prometheus-node-exporter -``` - -### kube-rbac-proxy - -You can enable `prometheus-node-exporter` endpoint protection using `kube-rbac-proxy`. By setting `kubeRBACProxy.enabled: true`, this chart will deploy a RBAC proxy container protecting the node-exporter endpoint. -To authorize access, authenticate your requests (via a `ServiceAccount` for example) with a `ClusterRole` attached such as: - -```yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: prometheus-node-exporter-read -rules: - - apiGroups: [ "" ] - resources: ["services/node-exporter-prometheus-node-exporter"] - verbs: - - get -``` - -See [kube-rbac-proxy examples](https://github.com/brancz/kube-rbac-proxy/tree/master/examples/resource-attributes) for more details. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/NOTES.txt deleted file mode 100644 index db8584def8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/NOTES.txt +++ /dev/null @@ -1,29 +0,0 @@ -1. Get the application URL by running these commands: -{{- if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ template "prometheus-node-exporter.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus-node-exporter.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ template "prometheus-node-exporter.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo 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. - You can watch the status of by running 'kubectl get svc -w {{ template "prometheus-node-exporter.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ template "prometheus-node-exporter.namespace" . }} {{ template "prometheus-node-exporter.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ template "prometheus-node-exporter.namespace" . }} -l "app.kubernetes.io/name={{ template "prometheus-node-exporter.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:9100 to use your application" - kubectl port-forward --namespace {{ template "prometheus-node-exporter.namespace" . }} $POD_NAME 9100 -{{- end }} - -{{- if .Values.kubeRBACProxy.enabled}} - -kube-rbac-proxy endpoint protections is enabled: -- Metrics endpoints is now HTTPS -- Ensure that the client authenticates the requests (e.g. via service account) with the following role permissions: -``` -rules: - - apiGroups: [ "" ] - resources: ["services/{{ template "prometheus-node-exporter.fullname" . }}"] - verbs: - - get -``` -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/_helpers.tpl deleted file mode 100644 index 72a6db45a1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/_helpers.tpl +++ /dev/null @@ -1,236 +0,0 @@ -# Rancher -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "prometheus-node-exporter.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 "prometheus-node-exporter.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 "prometheus-node-exporter.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "prometheus-node-exporter.labels" -}} -helm.sh/chart: {{ include "prometheus-node-exporter.chart" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -app.kubernetes.io/component: metrics -app.kubernetes.io/part-of: {{ include "prometheus-node-exporter.name" . }} -{{ include "prometheus-node-exporter.selectorLabels" . }} -{{- with .Chart.AppVersion }} -app.kubernetes.io/version: {{ . | quote }} -{{- end }} -{{- with .Values.podLabels }} -{{ toYaml . }} -{{- end }} -{{- if .Values.releaseLabel }} -release: {{ .Release.Name }} -{{- end }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "prometheus-node-exporter.selectorLabels" -}} -app.kubernetes.io/name: {{ include "prometheus-node-exporter.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - - -{{/* -Create the name of the service account to use -*/}} -{{- define "prometheus-node-exporter.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "prometheus-node-exporter.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} - -{{/* -The image to use -*/}} -{{- define "prometheus-node-exporter.image" -}} -{{- $temp_registry := (include "system_default_registry" .) }} -{{- if .Values.image.sha }} -{{- fail "image.sha forbidden. Use image.digest instead" }} -{{- else if .Values.image.digest }} -{{- if $temp_registry }} -{{- printf "%s%s:%s@%s" $temp_registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.digest }} -{{- else if .Values.global.imageRegistry }} -{{- printf "%s/%s:%s@%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.digest }} -{{- else }} -{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.digest }} -{{- end }} -{{- else }} -{{- if $temp_registry }} -{{- printf "%s%s:%s" $temp_registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} -{{- else if .Values.global.imageRegistry }} -{{- printf "%s/%s:%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} -{{- else }} -{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Allow the release namespace to be overridden for multi-namespace deployments in combined charts -*/}} -{{- define "prometheus-node-exporter.namespace" -}} -{{- if .Values.namespaceOverride }} -{{- .Values.namespaceOverride }} -{{- else }} -{{- .Release.Namespace }} -{{- end }} -{{- end }} - -{{/* -Create the namespace name of the service monitor -*/}} -{{- define "prometheus-node-exporter.monitor-namespace" -}} -{{- if .Values.namespaceOverride }} -{{- .Values.namespaceOverride }} -{{- else }} -{{- if .Values.prometheus.monitor.namespace }} -{{- .Values.prometheus.monitor.namespace }} -{{- else }} -{{- .Release.Namespace }} -{{- end }} -{{- end }} -{{- end }} - -{{/* Sets default scrape limits for servicemonitor */}} -{{- define "servicemonitor.scrapeLimits" -}} -{{- with .sampleLimit }} -sampleLimit: {{ . }} -{{- end }} -{{- with .targetLimit }} -targetLimit: {{ . }} -{{- end }} -{{- with .labelLimit }} -labelLimit: {{ . }} -{{- end }} -{{- with .labelNameLengthLimit }} -labelNameLengthLimit: {{ . }} -{{- end }} -{{- with .labelValueLengthLimit }} -labelValueLengthLimit: {{ . }} -{{- end }} -{{- end }} - -{{/* -Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) -*/}} -{{- define "prometheus-node-exporter.imagePullSecrets" -}} -{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} - {{- if eq (typeOf .) "map[string]interface {}" }} -- {{ toYaml . | trim }} - {{- else }} -- name: {{ . }} - {{- end }} -{{- end }} -{{- end -}} - -{{/* -Create the namespace name of the pod monitor -*/}} -{{- define "prometheus-node-exporter.podmonitor-namespace" -}} -{{- if .Values.namespaceOverride }} -{{- .Values.namespaceOverride }} -{{- else }} -{{- if .Values.prometheus.podMonitor.namespace }} -{{- .Values.prometheus.podMonitor.namespace }} -{{- else }} -{{- .Release.Namespace }} -{{- end }} -{{- end }} -{{- end }} - -{{/* Sets default scrape limits for podmonitor */}} -{{- define "podmonitor.scrapeLimits" -}} -{{- with .sampleLimit }} -sampleLimit: {{ . }} -{{- end }} -{{- with .targetLimit }} -targetLimit: {{ . }} -{{- end }} -{{- with .labelLimit }} -labelLimit: {{ . }} -{{- end }} -{{- with .labelNameLengthLimit }} -labelNameLengthLimit: {{ . }} -{{- end }} -{{- with .labelValueLengthLimit }} -labelValueLengthLimit: {{ . }} -{{- end }} -{{- end }} - -{{/* Sets sidecar volumeMounts */}} -{{- define "prometheus-node-exporter.sidecarVolumeMounts" -}} -{{- range $_, $mount := $.Values.sidecarVolumeMount }} -- name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - readOnly: {{ $mount.readOnly }} -{{- end }} -{{- range $_, $mount := $.Values.sidecarHostVolumeMounts }} -- name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - readOnly: {{ $mount.readOnly }} -{{- if $mount.mountPropagation }} - mountPropagation: {{ $mount.mountPropagation }} -{{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/clusterrole.yaml deleted file mode 100644 index c256dba73d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/clusterrole.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if and (eq .Values.rbac.create true) (eq .Values.kubeRBACProxy.enabled true) -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} -rules: - {{- if $.Values.kubeRBACProxy.enabled }} - - apiGroups: [ "authentication.k8s.io" ] - resources: - - tokenreviews - verbs: [ "create" ] - - apiGroups: [ "authorization.k8s.io" ] - resources: - - subjectaccessreviews - verbs: [ "create" ] - {{- end }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml deleted file mode 100644 index 653305ad9e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and (eq .Values.rbac.create true) (eq .Values.kubeRBACProxy.enabled true) -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} - name: {{ template "prometheus-node-exporter.fullname" . }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole -{{- if .Values.rbac.useExistingRole }} - name: {{ .Values.rbac.useExistingRole }} -{{- else }} - name: {{ template "prometheus-node-exporter.fullname" . }} -{{- end }} -subjects: -- kind: ServiceAccount - name: {{ template "prometheus-node-exporter.serviceAccountName" . }} - namespace: {{ template "prometheus-node-exporter.namespace" . }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/daemonset.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/daemonset.yaml deleted file mode 100644 index 7f91a8d2b1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/daemonset.yaml +++ /dev/null @@ -1,312 +0,0 @@ -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} - {{- with .Values.daemonsetAnnotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: - {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} - revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} - {{- with .Values.updateStrategy }} - updateStrategy: - {{- toYaml . | nindent 4 }} - {{- end }} - template: - metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 8 }} - spec: - automountServiceAccountToken: {{ ternary true false (or .Values.serviceAccount.automountServiceAccountToken .Values.kubeRBACProxy.enabled) }} - {{- with .Values.securityContext }} - securityContext: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.priorityClassName }} - priorityClassName: {{ . }} - {{- end }} - {{- with .Values.extraInitContainers }} - initContainers: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "prometheus-node-exporter.serviceAccountName" . }} - {{- with .Values.terminationGracePeriodSeconds }} - terminationGracePeriodSeconds: {{ . }} - {{- end }} - containers: - {{- $servicePort := ternary .Values.kubeRBACProxy.port .Values.service.port .Values.kubeRBACProxy.enabled }} - - name: node-exporter - image: {{ include "prometheus-node-exporter.image" . }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - args: - - --path.procfs=/host/proc - - --path.sysfs=/host/sys - {{- if .Values.hostRootFsMount.enabled }} - - --path.rootfs=/host/root - {{- if semverCompare ">=1.4.0-0" (coalesce .Values.version .Values.image.tag .Chart.AppVersion) }} - - --path.udev.data=/host/root/run/udev/data - {{- end }} - {{- end }} - - --web.listen-address=[$(HOST_IP)]:{{ $servicePort }} - {{- with .Values.extraArgs }} - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.containerSecurityContext }} - securityContext: - {{- toYaml . | nindent 12 }} - {{- end }} - env: - - name: HOST_IP - {{- if .Values.kubeRBACProxy.enabled }} - value: 127.0.0.1 - {{- else if .Values.service.listenOnAllInterfaces }} - value: 0.0.0.0 - {{- else }} - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: status.hostIP - {{- end }} - {{- range $key, $value := .Values.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - {{- if eq .Values.kubeRBACProxy.enabled false }} - ports: - - name: {{ .Values.service.portName }} - containerPort: {{ .Values.service.port }} - protocol: TCP - {{- end }} - livenessProbe: - failureThreshold: {{ .Values.livenessProbe.failureThreshold }} - httpGet: - {{- if .Values.kubeRBACProxy.enabled }} - host: 127.0.0.1 - {{- end }} - httpHeaders: - {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} - - name: {{ $header.name }} - value: {{ $header.value }} - {{- end }} - path: / - port: {{ $servicePort }} - scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} - initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.livenessProbe.periodSeconds }} - successThreshold: {{ .Values.livenessProbe.successThreshold }} - timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} - readinessProbe: - failureThreshold: {{ .Values.readinessProbe.failureThreshold }} - httpGet: - {{- if .Values.kubeRBACProxy.enabled }} - host: 127.0.0.1 - {{- end }} - httpHeaders: - {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} - - name: {{ $header.name }} - value: {{ $header.value }} - {{- end }} - path: / - port: {{ $servicePort }} - scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} - initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.readinessProbe.periodSeconds }} - successThreshold: {{ .Values.readinessProbe.successThreshold }} - timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} - {{- with .Values.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- if .Values.terminationMessageParams.enabled }} - {{- with .Values.terminationMessageParams }} - terminationMessagePath: {{ .terminationMessagePath }} - terminationMessagePolicy: {{ .terminationMessagePolicy }} - {{- end }} - {{- end }} - volumeMounts: - - name: proc - mountPath: /host/proc - {{- with .Values.hostProcFsMount.mountPropagation }} - mountPropagation: {{ . }} - {{- end }} - readOnly: true - - name: sys - mountPath: /host/sys - {{- with .Values.hostSysFsMount.mountPropagation }} - mountPropagation: {{ . }} - {{- end }} - readOnly: true - {{- if .Values.hostRootFsMount.enabled }} - - name: root - mountPath: /host/root - {{- with .Values.hostRootFsMount.mountPropagation }} - mountPropagation: {{ . }} - {{- end }} - readOnly: true - {{- end }} - {{- range $_, $mount := .Values.extraHostVolumeMounts }} - - name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - readOnly: {{ $mount.readOnly }} - {{- with $mount.mountPropagation }} - mountPropagation: {{ . }} - {{- end }} - {{- end }} - {{- range $_, $mount := .Values.sidecarVolumeMount }} - - name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - readOnly: true - {{- end }} - {{- range $_, $mount := .Values.configmaps }} - - name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - {{- end }} - {{- range $_, $mount := .Values.secrets }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - {{- end }} - {{- range .Values.sidecars }} - {{- $overwrites := dict "volumeMounts" (concat (include "prometheus-node-exporter.sidecarVolumeMounts" $ | fromYamlArray) (.volumeMounts | default list) | default list) }} - {{- $defaults := dict "image" (include "prometheus-node-exporter.image" $) "securityContext" $.Values.containerSecurityContext "imagePullPolicy" $.Values.image.pullPolicy }} - - {{- toYaml (merge $overwrites . $defaults) | nindent 10 }} - {{- end }} - {{- if .Values.kubeRBACProxy.enabled }} - - name: kube-rbac-proxy - args: - {{- if .Values.kubeRBACProxy.extraArgs }} - {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 12 }} - {{- end }} - - --secure-listen-address=:{{ .Values.service.port}} - - --upstream=http://127.0.0.1:{{ $servicePort }}/ - - --proxy-endpoints-port={{ .Values.kubeRBACProxy.proxyEndpointsPort }} - - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml - volumeMounts: - - name: kube-rbac-proxy-config - mountPath: /etc/kube-rbac-proxy-config - imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} - {{- $base_registry := (include "monitoring_registry" .) }} - {{- if .Values.kubeRBACProxy.image.sha }} - image: "{{ $base_registry | default .Values.kubeRBACProxy.image.registry}}/{{ .Values.kubeRBACProxy.image.repository }}:{{ .Values.kubeRBACProxy.image.tag }}@sha256:{{ .Values.kubeRBACProxy.image.sha }}" - {{- else }} - image: "{{ $base_registry | default .Values.kubeRBACProxy.image.registry}}/{{ .Values.kubeRBACProxy.image.repository }}:{{ .Values.kubeRBACProxy.image.tag }}" - {{- end }} - ports: - - containerPort: {{ .Values.service.port}} - name: {{ .Values.kubeRBACProxy.portName }} - {{- if .Values.kubeRBACProxy.enableHostPort }} - hostPort: {{ .Values.service.port }} - {{- end }} - - containerPort: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} - {{- if .Values.kubeRBACProxy.enableProxyEndpointsHostPort }} - hostPort: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} - {{- end }} - name: "http-healthz" - readinessProbe: - httpGet: - scheme: HTTPS - port: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} - path: healthz - initialDelaySeconds: 5 - timeoutSeconds: 5 - {{- if .Values.kubeRBACProxy.resources }} - resources: - {{- toYaml .Values.kubeRBACProxy.resources | nindent 12 }} - {{- end }} - {{- if .Values.terminationMessageParams.enabled }} - {{- with .Values.terminationMessageParams }} - terminationMessagePath: {{ .terminationMessagePath }} - terminationMessagePolicy: {{ .terminationMessagePolicy }} - {{- end }} - {{- end }} - {{- with .Values.kubeRBACProxy.env }} - env: - {{- range $key, $value := $.Values.kubeRBACProxy.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - {{- end }} - {{- if .Values.kubeRBACProxy.containerSecurityContext }} - securityContext: - {{ toYaml .Values.kubeRBACProxy.containerSecurityContext | nindent 12 }} - {{- end }} - {{- end }} - {{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- include "prometheus-node-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} - {{- end }} - hostNetwork: {{ .Values.hostNetwork }} - hostPID: {{ .Values.hostPID }} - {{- with .Values.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.dnsConfig }} - dnsConfig: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.restartPolicy }} - restartPolicy: {{ . }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - volumes: - - name: proc - hostPath: - path: /proc - - name: sys - hostPath: - path: /sys - {{- if .Values.hostRootFsMount.enabled }} - - name: root - hostPath: - path: / - {{- end }} - {{- range $_, $mount := .Values.extraHostVolumeMounts }} - - name: {{ $mount.name }} - hostPath: - path: {{ $mount.hostPath }} - {{- with $mount.type }} - type: {{ . }} - {{- end }} - {{- end }} - {{- range $_, $mount := .Values.sidecarVolumeMount }} - - name: {{ $mount.name }} - emptyDir: - medium: Memory - {{- end }} - {{- range $_, $mount := .Values.sidecarHostVolumeMounts }} - - name: {{ $mount.name }} - hostPath: - path: {{ $mount.hostPath }} - {{- end }} - {{- range $_, $mount := .Values.configmaps }} - - name: {{ $mount.name }} - configMap: - name: {{ $mount.name }} - {{- end }} - {{- range $_, $mount := .Values.secrets }} - - name: {{ $mount.name }} - secret: - secretName: {{ $mount.name }} - {{- end }} - {{- if .Values.kubeRBACProxy.enabled }} - - name: kube-rbac-proxy-config - configMap: - name: {{ template "prometheus-node-exporter.fullname" . }}-rbac-config - {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/endpoints.yaml deleted file mode 100644 index 56b695203a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/endpoints.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.endpoints }} -apiVersion: v1 -kind: Endpoints -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} -subsets: - - addresses: - {{- range .Values.endpoints }} - - ip: {{ . }} - {{- end }} - ports: - - name: {{ .Values.service.portName }} - port: {{ .Values.service.port }} - protocol: TCP -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/extra-manifests.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/extra-manifests.yaml deleted file mode 100644 index 2b21b71062..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/extra-manifests.yaml +++ /dev/null @@ -1,4 +0,0 @@ -{{ range .Values.extraManifests }} ---- -{{ tpl . $ }} -{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/networkpolicy.yaml deleted file mode 100644 index 825722729d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/networkpolicy.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if .Values.networkPolicy.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" $ | nindent 4 }} - {{- with .Values.service.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - ingress: - - ports: - - port: {{ .Values.service.port }} - policyTypes: - - Egress - - Ingress - podSelector: - matchLabels: - {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/podmonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/podmonitor.yaml deleted file mode 100644 index f88da6a34e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/podmonitor.yaml +++ /dev/null @@ -1,91 +0,0 @@ -{{- if .Values.prometheus.podMonitor.enabled }} -apiVersion: {{ .Values.prometheus.podMonitor.apiVersion | default "monitoring.coreos.com/v1" }} -kind: PodMonitor -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.podmonitor-namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} - {{- with .Values.prometheus.podMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.podMonitor.jobLabel }} - {{- include "podmonitor.scrapeLimits" .Values.prometheus.podMonitor | nindent 2 }} - selector: - matchLabels: - {{- with .Values.prometheus.podMonitor.selectorOverride }} - {{- toYaml . | nindent 6 }} - {{- else }} - {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} - {{- end }} - namespaceSelector: - matchNames: - - {{ include "prometheus-node-exporter.namespace" . }} - {{- with .Values.prometheus.podMonitor.attachMetadata }} - attachMetadata: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.podTargetLabels }} - podTargetLabels: - {{- toYaml . | nindent 4 }} - {{- end }} - podMetricsEndpoints: - - port: {{ .Values.service.portName }} - {{- with .Values.prometheus.podMonitor.scheme }} - scheme: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.path }} - path: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.basicAuth }} - basicAuth: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.bearerTokenSecret }} - bearerTokenSecret: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.tlsConfig }} - tlsConfig: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.authorization }} - authorization: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.oauth2 }} - oauth2: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.proxyUrl }} - proxyUrl: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.interval }} - interval: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.honorTimestamps }} - honorTimestamps: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.honorLabels }} - honorLabels: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.scrapeTimeout }} - scrapeTimeout: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.relabelings }} - relabelings: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.metricRelabelings }} - metricRelabelings: - {{- toYaml . | nindent 8 }} - {{- end }} - enableHttp2: {{ default false .Values.prometheus.podMonitor.enableHttp2 }} - filterRunning: {{ default true .Values.prometheus.podMonitor.filterRunning }} - followRedirects: {{ default false .Values.prometheus.podMonitor.followRedirects }} - {{- with .Values.prometheus.podMonitor.params }} - params: - {{- toYaml . | nindent 8 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml deleted file mode 100644 index 8957317243..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: psp-{{ include "prometheus-node-exporter.fullname" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} -rules: -- apiGroups: ['extensions'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ include "prometheus-node-exporter.fullname" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml deleted file mode 100644 index 333370173b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: psp-{{ include "prometheus-node-exporter.fullname" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: psp-{{ include "prometheus-node-exporter.fullname" . }} -subjects: - - kind: ServiceAccount - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp.yaml deleted file mode 100644 index 4896c84daa..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/psp.yaml +++ /dev/null @@ -1,49 +0,0 @@ -{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} - {{- with .Values.rbac.pspAnnotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - privileged: false - # Allow core volume types. - volumes: - - 'configMap' - - 'emptyDir' - - 'projected' - - 'secret' - - 'downwardAPI' - - 'persistentVolumeClaim' - - 'hostPath' - hostNetwork: true - hostIPC: false - hostPID: true - hostPorts: - - min: 0 - max: 65535 - runAsUser: - # Permits the container to run with root privileges as well. - rule: 'RunAsAny' - seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - readOnlyRootFilesystem: false -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/rbac-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/rbac-configmap.yaml deleted file mode 100644 index 814e110337..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/rbac-configmap.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.kubeRBACProxy.enabled}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "prometheus-node-exporter.fullname" . }}-rbac-config - namespace: {{ include "prometheus-node-exporter.namespace" . }} -data: - config-file.yaml: |+ - authorization: - resourceAttributes: - namespace: {{ template "prometheus-node-exporter.namespace" . }} - apiVersion: v1 - resource: services - subresource: {{ template "prometheus-node-exporter.fullname" . }} - name: {{ template "prometheus-node-exporter.fullname" . }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/service.yaml deleted file mode 100644 index 8308b7b2b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/service.yaml +++ /dev/null @@ -1,35 +0,0 @@ -{{- if .Values.service.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" $ | nindent 4 }} - {{- with .Values.service.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: -{{- if .Values.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} -{{- end }} -{{- if .Values.service.externalTrafficPolicy }} - externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} -{{- end }} - type: {{ .Values.service.type }} -{{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} - clusterIP: "{{ .Values.service.clusterIP }}" -{{- end }} - ports: - - port: {{ .Values.service.port }} - {{- if ( and (eq .Values.service.type "NodePort" ) (not (empty .Values.service.nodePort)) ) }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} - targetPort: {{ .Values.service.targetPort }} - protocol: TCP - name: {{ .Values.service.portName }} - selector: - {{- include "prometheus-node-exporter.selectorLabels" . | nindent 4 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/serviceaccount.yaml deleted file mode 100644 index 462b0cda4b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/serviceaccount.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.rbac.create .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "prometheus-node-exporter.serviceAccountName" . }} - namespace: {{ include "prometheus-node-exporter.namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} -{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} -imagePullSecrets: - {{- include "prometheus-node-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} -{{- end }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/servicemonitor.yaml deleted file mode 100644 index abe6c73c1b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/servicemonitor.yaml +++ /dev/null @@ -1,71 +0,0 @@ -{{- if .Values.prometheus.monitor.enabled }} -apiVersion: {{ .Values.prometheus.monitor.apiVersion | default "monitoring.coreos.com/v1" }} -kind: ServiceMonitor -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.monitor-namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} - {{- with .Values.prometheus.monitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} - {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | nindent 2 }} - {{- with .Values.prometheus.monitor.podTargetLabels }} - podTargetLabels: - {{- toYaml . | nindent 4 }} - {{- end }} - selector: - matchLabels: - {{- with .Values.prometheus.monitor.selectorOverride }} - {{- toYaml . | nindent 6 }} - {{- else }} - {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} - {{- end }} - {{- with .Values.prometheus.monitor.attachMetadata }} - attachMetadata: - {{- toYaml . | nindent 4 }} - {{- end }} - endpoints: - - port: {{ .Values.service.portName }} - scheme: {{ .Values.prometheus.monitor.scheme }} - {{- with .Values.prometheus.monitor.basicAuth }} - basicAuth: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.monitor.bearerTokenFile }} - bearerTokenFile: {{ . }} - {{- end }} - {{- with .Values.prometheus.monitor.tlsConfig }} - tlsConfig: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.monitor.proxyUrl }} - proxyUrl: {{ . }} - {{- end }} - {{- with .Values.prometheus.monitor.interval }} - interval: {{ . }} - {{- end }} - {{- with .Values.prometheus.monitor.scrapeTimeout }} - scrapeTimeout: {{ . }} - {{- end }} - {{- with .Values.prometheus.monitor.relabelings }} - relabelings: - {{- toYaml . | nindent 8 }} - {{- end }} - metricRelabelings: - {{- with .Values.prometheus.monitor.metricRelabelings }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName }} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml deleted file mode 100644 index 2c2705f872..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.verticalPodAutoscaler.enabled) }} -apiVersion: autoscaling.k8s.io/v1 -kind: VerticalPodAutoscaler -metadata: - name: {{ include "prometheus-node-exporter.fullname" . }} - namespace: {{ include "prometheus-node-exporter.namespace" . }} - labels: - {{- include "prometheus-node-exporter.labels" . | nindent 4 }} -spec: - {{- with .Values.verticalPodAutoscaler.recommenders }} - recommenders: - {{- toYaml . | nindent 4 }} - {{- end }} - resourcePolicy: - containerPolicies: - - containerName: node-exporter - {{- with .Values.verticalPodAutoscaler.controlledResources }} - controlledResources: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.verticalPodAutoscaler.controlledValues }} - controlledValues: {{ . }} - {{- end }} - {{- with .Values.verticalPodAutoscaler.maxAllowed }} - maxAllowed: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.verticalPodAutoscaler.minAllowed }} - minAllowed: - {{- toYaml . | nindent 8 }} - {{- end }} - targetRef: - apiVersion: apps/v1 - kind: DaemonSet - name: {{ include "prometheus-node-exporter.fullname" . }} - {{- with .Values.verticalPodAutoscaler.updatePolicy }} - updatePolicy: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/values.yaml deleted file mode 100644 index b02d92650a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/prometheus-node-exporter/values.yaml +++ /dev/null @@ -1,539 +0,0 @@ -# Default values for prometheus-node-exporter. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -image: - registry: docker.io - repository: rancher/mirrored-prometheus-node-exporter - # Overrides the image tag whose default is {{ printf "v%s" .Chart.AppVersion }} - tag: v1.8.2 - pullPolicy: IfNotPresent - digest: "" - -imagePullSecrets: [] -# - name: "image-pull-secret" -nameOverride: "" -fullnameOverride: "" - -# Number of old history to retain to allow rollback -# Default Kubernetes value is set to 10 -revisionHistoryLimit: 10 - -global: - cattle: - systemDefaultRegistry: "" - - # To help compatibility with other charts which use global.imagePullSecrets. - # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). - # global: - # imagePullSecrets: - # - name: pullSecret1 - # - name: pullSecret2 - # or - # global: - # imagePullSecrets: - # - pullSecret1 - # - pullSecret2 - imagePullSecrets: [] - # - # Allow parent charts to override registry hostname - imageRegistry: "" - -# Configure kube-rbac-proxy. When enabled, creates a kube-rbac-proxy to protect the node-exporter http endpoint. -# The requests are served through the same service but requests are HTTPS. -kubeRBACProxy: - enabled: false - ## Set environment variables as name/value pairs - env: {} - # VARIABLE: value - image: - registry: docker.io - repository: rancher/mirrored-brancz-kube-rbac-proxy - tag: v0.18.0 - sha: "" - pullPolicy: IfNotPresent - - # List of additional cli arguments to configure kube-rbac-proxy - # for example: --tls-cipher-suites, --log-file, etc. - # all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage - extraArgs: [] - - ## Specify security settings for a Container - ## Allows overrides and additional options compared to (Pod) securityContext - ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container - containerSecurityContext: {} - - # Specify the port used for the Node exporter container (upstream port) - port: 8100 - # Specify the name of the container port - portName: http - # Configure a hostPort. If true, hostPort will be enabled in the container and set to service.port. - enableHostPort: false - - # Configure Proxy Endpoints Port - # This is the port being probed for readiness - proxyEndpointsPort: 8888 - # Configure a hostPort. If true, hostPort will be enabled in the container and set to proxyEndpointsPort. - enableProxyEndpointsHostPort: false - - 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: 64Mi - # requests: - # cpu: 10m - # memory: 32Mi - -service: - enabled: true - type: ClusterIP - clusterIP: "" - port: 9796 - targetPort: 9796 - nodePort: - portName: metrics - listenOnAllInterfaces: true - annotations: - prometheus.io/scrape: "true" - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - externalTrafficPolicy: "" - -# Set a NetworkPolicy with: -# ingress only on service.port -# no egress permitted -networkPolicy: - enabled: false - -# Additional environment variables that will be passed to the daemonset -env: {} -## env: -## VARIABLE: value - -prometheus: - monitor: - enabled: false - additionalLabels: {} - namespace: "" - - jobLabel: "" - - # List of pod labels to add to node exporter metrics - # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor - podTargetLabels: [] - - scheme: http - basicAuth: {} - bearerTokenFile: - tlsConfig: {} - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## Override serviceMonitor selector - ## - selectorOverride: {} - - ## Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. - ## - attachMetadata: - node: false - - relabelings: [] - metricRelabelings: [] - interval: "" - scrapeTimeout: 10s - ## prometheus.monitor.apiVersion ApiVersion for the serviceMonitor Resource(defaults to "monitoring.coreos.com/v1") - apiVersion: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - # PodMonitor defines monitoring for a set of pods. - # ref. https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor - # Using a PodMonitor may be preferred in some environments where there is very large number - # of Node Exporter endpoints (1000+) behind a single service. - # The PodMonitor is disabled by default. When switching from ServiceMonitor to PodMonitor, - # the time series resulting from the configuration through PodMonitor may have different labels. - # For instance, there will not be the service label any longer which might - # affect PromQL queries selecting that label. - podMonitor: - enabled: false - # Namespace in which to deploy the pod monitor. Defaults to the release namespace. - namespace: "" - # Additional labels, e.g. setting a label for pod monitor selector as set in prometheus - additionalLabels: {} - # release: kube-prometheus-stack - # PodTargetLabels transfers labels of the Kubernetes Pod onto the target. - podTargetLabels: [] - # apiVersion defaults to monitoring.coreos.com/v1. - apiVersion: "" - # Override pod selector to select pod objects. - selectorOverride: {} - # Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. - attachMetadata: - node: false - # The label to use to retrieve the job name from. Defaults to label app.kubernetes.io/name. - jobLabel: "" - - # Scheme/protocol to use for scraping. - scheme: "http" - # Path to scrape metrics at. - path: "/metrics" - - # BasicAuth allow an endpoint to authenticate over basic authentication. - # More info: https://prometheus.io/docs/operating/configuration/#endpoint - basicAuth: {} - # Secret to mount to read bearer token for scraping targets. - # The secret needs to be in the same namespace as the pod monitor and accessible by the Prometheus Operator. - # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secretkeyselector-v1-core - bearerTokenSecret: {} - # TLS configuration to use when scraping the endpoint. - tlsConfig: {} - # Authorization section for this endpoint. - # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.SafeAuthorization - authorization: {} - # OAuth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer. - # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.OAuth2 - oauth2: {} - - # ProxyURL eg http://proxyserver:2195. Directs scrapes through proxy to this endpoint. - proxyUrl: "" - # Interval at which endpoints should be scraped. If not specified Prometheus’ global scrape interval is used. - interval: "" - # Timeout after which the scrape is ended. If not specified, the Prometheus global scrape interval is used. - scrapeTimeout: "" - # HonorTimestamps controls whether Prometheus respects the timestamps present in scraped data. - honorTimestamps: true - # HonorLabels chooses the metric’s labels on collisions with target labels. - honorLabels: true - # Whether to enable HTTP2. Default false. - enableHttp2: "" - # Drop pods that are not running. (Failed, Succeeded). - # Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase - filterRunning: "" - # FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. Default false. - followRedirects: "" - # Optional HTTP URL parameters - params: {} - - # RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds - # relabelings for a few standard Kubernetes fields. The original scrape job’s name - # is available via the __tmp_prometheus_job_name label. - # More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config - relabelings: [] - # MetricRelabelConfigs to apply to samples before ingestion. - metricRelabelings: [] - - # SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - sampleLimit: 0 - # TargetLimit defines a limit on the number of scraped targets that will be accepted. - targetLimit: 0 - # Per-scrape limit on number of labels that will be accepted for a sample. - # Only valid in Prometheus versions 2.27.0 and newer. - labelLimit: 0 - # Per-scrape limit on length of labels name that will be accepted for a sample. - # Only valid in Prometheus versions 2.27.0 and newer. - labelNameLengthLimit: 0 - # Per-scrape limit on length of labels value that will be accepted for a sample. - # Only valid in Prometheus versions 2.27.0 and newer. - labelValueLengthLimit: 0 - -## Customize the updateStrategy if set -updateStrategy: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 1 - -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: 200m - # memory: 50Mi - # requests: - # cpu: 100m - # memory: 30Mi - -# Specify the container restart policy passed to the Node Export container -# Possible Values: Always (default)|OnFailure|Never -restartPolicy: null - -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: {} - imagePullSecrets: [] - automountServiceAccountToken: false - -securityContext: - fsGroup: 65534 - runAsGroup: 65534 - runAsNonRoot: true - runAsUser: 65534 - -containerSecurityContext: - readOnlyRootFilesystem: true - # capabilities: - # add: - # - SYS_TIME - -rbac: - ## If true, create & use RBAC resources - ## - create: true - ## If true, create & use Pod Security Policy resources - ## https://kubernetes.io/docs/concepts/policy/pod-security-policy/ - pspEnabled: true - pspAnnotations: {} - -# for deployments that have node_exporter deployed outside of the cluster, list -# their addresses here -endpoints: [] - -# Expose the service to the host network -hostNetwork: true - -# Share the host process ID namespace -hostPID: true - -# Mount the node's root file system (/) at /host/root in the container -hostRootFsMount: - enabled: true - # Defines how new mounts in existing mounts on the node or in the container - # are propagated to the container or node, respectively. Possible values are - # None, HostToContainer, and Bidirectional. If this field is omitted, then - # None is used. More information on: - # https://kubernetes.io/docs/concepts/storage/volumes/#mount-propagation - mountPropagation: HostToContainer - -# Mount the node's proc file system (/proc) at /host/proc in the container -hostProcFsMount: - # Possible values are None, HostToContainer, and Bidirectional - mountPropagation: "" - -# Mount the node's sys file system (/sys) at /host/sys in the container -hostSysFsMount: - # Possible values are None, HostToContainer, and Bidirectional - mountPropagation: "" - -## Assign a group of affinity scheduling rules -## -affinity: {} -# nodeAffinity: -# requiredDuringSchedulingIgnoredDuringExecution: -# nodeSelectorTerms: -# - matchFields: -# - key: metadata.name -# operator: In -# values: -# - target-host-name - -# Annotations to be added to node exporter pods -podAnnotations: - # Fix for very slow GKE cluster upgrades - cluster-autoscaler.kubernetes.io/safe-to-evict: "true" - -# Extra labels to be added to node exporter pods -podLabels: {} - -# Annotations to be added to node exporter daemonset -daemonsetAnnotations: {} - -## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box -releaseLabel: false - -# Custom DNS configuration to be added to prometheus-node-exporter pods -dnsConfig: {} -# nameservers: -# - 1.2.3.4 -# searches: -# - ns1.svc.cluster-domain.example -# - my.dns.search.suffix -# options: -# - name: ndots -# value: "2" -# - name: edns0 - -## Assign a nodeSelector if operating a hybrid cluster -## -nodeSelector: - kubernetes.io/os: linux - # kubernetes.io/arch: amd64 - -# Specify grace period for graceful termination of pods. Defaults to 30 if null or not specified -terminationGracePeriodSeconds: null - -tolerations: - - effect: NoSchedule - operator: Exists - - effect: NoExecute - operator: Exists - -# Enable or disable container termination message settings -# https://kubernetes.io/docs/tasks/debug/debug-application/determine-reason-pod-failure/ -terminationMessageParams: - enabled: false - # If enabled, specify the path for termination messages - terminationMessagePath: /dev/termination-log - # If enabled, specify the policy for termination messages - terminationMessagePolicy: File - - -## Assign a PriorityClassName to pods if set -# priorityClassName: "" - -## Additional container arguments -## -extraArgs: [] -# - --collector.diskstats.ignored-devices=^(ram|loop|fd|(h|s|v)d[a-z]|nvme\\d+n\\d+p)\\d+$ -# - --collector.textfile.directory=/run/prometheus - -## Additional mounts from the host to node-exporter container -## -extraHostVolumeMounts: [] -# - name: -# hostPath: -# https://kubernetes.io/docs/concepts/storage/volumes/#hostpath-volume-types -# type: "" (Default)|DirectoryOrCreate|Directory|FileOrCreate|File|Socket|CharDevice|BlockDevice -# mountPath: -# readOnly: true|false -# mountPropagation: None|HostToContainer|Bidirectional - -## Additional configmaps to be mounted. -## -configmaps: [] -# - name: -# mountPath: -secrets: [] -# - name: -# mountPath: -## Override the deployment namespace -## -namespaceOverride: "" - -## Additional containers for export metrics to text file; fields image,imagePullPolicy,securityContext take default value from main container -## -sidecars: [] -# - name: nvidia-dcgm-exporter -# image: nvidia/dcgm-exporter:1.4.3 -# volumeMounts: -# - name: tmp -# mountPath: /tmp - -## Volume for sidecar containers -## -sidecarVolumeMount: [] -# - name: collector-textfiles -# mountPath: /run/prometheus -# readOnly: false - -## Additional mounts from the host to sidecar containers -## -sidecarHostVolumeMounts: [] -# - name: -# hostPath: -# mountPath: -# readOnly: true|false -# mountPropagation: None|HostToContainer|Bidirectional - -## Additional InitContainers to initialize the pod -## -extraInitContainers: [] - -## Liveness probe -## -livenessProbe: - failureThreshold: 3 - httpGet: - httpHeaders: [] - scheme: http - initialDelaySeconds: 0 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - -## Readiness probe -## -readinessProbe: - failureThreshold: 3 - httpGet: - httpHeaders: [] - scheme: http - initialDelaySeconds: 0 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - -# Enable vertical pod autoscaler support for prometheus-node-exporter -verticalPodAutoscaler: - enabled: false - - # Recommender 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: - # - name: custom-recommender-performance - - # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory - controlledResources: [] - # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. - # controlledValues: RequestsAndLimits - - # Define the max allowed resources for the pod - maxAllowed: {} - # cpu: 200m - # memory: 100Mi - # Define the min allowed resources for the pod - minAllowed: {} - # cpu: 200m - # memory: 100Mi - - # 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 - -# Extra manifests to deploy as an array -extraManifests: [] - # - | - # apiVersion: v1 - # kind: ConfigMap - # metadata: - # name: prometheus-extra - # data: - # extra-data: "value" - -# Override version of app, required if image.tag is defined and does not follow semver -version: "" diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/Chart.yaml deleted file mode 100644 index 50c3f10dcd..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rke2ControllerManager -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2ControllerManager/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/Chart.yaml deleted file mode 100644 index 8a530669f5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rke2Etcd -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Etcd/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/Chart.yaml deleted file mode 100644 index d62e4a18e8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rke2IngressNginx -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2IngressNginx/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/Chart.yaml deleted file mode 100644 index 2b9214f36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rke2Proxy -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Proxy/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/Chart.yaml deleted file mode 100644 index e9a8ec1dd1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rke2Scheduler -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rke2Scheduler/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/Chart.yaml deleted file mode 100644 index be2490c018..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rkeControllerManager -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeControllerManager/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/Chart.yaml deleted file mode 100644 index 897ef6303d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rkeEtcd -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeEtcd/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/Chart.yaml deleted file mode 100644 index 2a8ff34be7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rkeIngressNginx -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeIngressNginx/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/Chart.yaml deleted file mode 100644 index c68de64c60..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rkeProxy -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeProxy/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/Chart.yaml deleted file mode 100644 index cdb17fa2fb..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - catalog.cattle.io/hidden: "true" - catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' - catalog.cattle.io/os: linux - catalog.rancher.io/certified: rancher - catalog.rancher.io/namespace: cattle-monitoring-system - catalog.rancher.io/release-name: rancher-pushprox -apiVersion: v1 -appVersion: 0.1.0 -description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx - clients. -kubeVersion: '>=1.28.0-0' -name: rkeScheduler -type: application -version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/README.md deleted file mode 100644 index 345002f48a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# rancher-pushprox - -A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. - -Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. - -Using an instance of this chart is suitable for the following scenarios: -- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) -- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) -- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` -- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) -- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) - -The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. - -## Upgrading to Kubernetes v1.25+ - -Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. - -As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. -​ -> **Note:** -> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. - -> **Note:** -> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** -> -> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. - -Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. - -As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. - -## Configuration - -The following tables list the configurable parameters of the rancher-pushprox chart and their default values. - -### General - -#### Required -| Parameter | Description | Example | -| ----- | ----------- | ------ | -| `component` | The component that is being monitored | `kube-etcd` -| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | -| `namespaceOverride` | The namespace to install the chart | `""` - -#### Optional -| Parameter | Description | Default | -| ----- | ----------- | ------ | -| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | -| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | -| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | -| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | -| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | -| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | -| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | -| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | -| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | -| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | -| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | -| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | -| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | -| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | -| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | -| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | -| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | -| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | -| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | -| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | -| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | -| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | -| `clients.resources` | Set resource limits and requests for the client container | `{}` | -| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | -| `clients.tolerations` | Specify tolerations for clients | `[]` | -| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | -| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | -| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | -| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | -| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | -| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` - -*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. - -See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/_helpers.tpl deleted file mode 100644 index 1ba5093944..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/_helpers.tpl +++ /dev/null @@ -1,170 +0,0 @@ -# Rancher - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# General - -{{- define "applyKubeVersionOverrides" -}} -{{- $overrides := dict -}} -{{- range $override := .Values.kubeVersionOverrides -}} -{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} -{{- $_ := mergeOverwrite $overrides $override.values -}} -{{- end -}} -{{- end -}} -{{- $_ := mergeOverwrite .Values $overrides -}} -{{- end -}} - -{{- define "pushprox.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{- define "pushProxy.commonLabels" -}} -release: {{ .Release.Name }} -component: {{ .Values.component | quote }} -provider: kubernetes -{{- end -}} - -{{- define "pushProxy.proxyUrl" -}} -{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} -{{- if .Values.clients.proxyUrl -}} -{{ printf "%s" .Values.clients.proxyUrl }} -{{- else -}} -{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} -{{- end -}}{{- end -}} - -# Client - -{{- define "pushProxy.client.name" -}} -{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.serviceAccountTokenName" -}} -{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.client.labels" -}} -k8s-app: {{ template "pushProxy.client.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# Proxy - -{{- define "pushProxy.proxy.name" -}} -{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.proxy.labels" -}} -k8s-app: {{ template "pushProxy.proxy.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -# ServiceMonitor - -{{- define "pushprox.serviceMonitor.name" -}} -{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.labels" -}} -app: {{ template "pushprox.serviceMonitor.name" . }} -{{ template "pushProxy.commonLabels" . }} -{{- end -}} - -{{- define "pushProxy.serviceMonitor.endpoints" -}} -{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} -{{- $useHTTPS := .Values.clients.https.enabled -}} -{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} -{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} -{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} -{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} -{{- $metricRelabelings := list }} -{{- $endpoints := .Values.serviceMonitor.endpoints }} -{{- if .Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- range $endpoints }} -{{- if $.Values.proxy.enabled }} -{{- $_ := set . "proxyUrl" $proxyURL }} -{{- end }} -{{- $clusterIdRelabel := dict }} -{{- $metricRelabelings := list }} -{{- if $.Values.global.cattle.clusterId }} -{{- $_ := set $clusterIdRelabel "action" "replace" }} -{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} -{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} -{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} -{{- end }} -{{- $clusterNameRelabel := dict }} -{{- if $.Values.global.cattle.clusterName }} -{{- $_ := set $clusterNameRelabel "action" "replace" }} -{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} -{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} -{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} -{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} -{{- end }} -{{- if not (empty $metricRelabelings) }} -{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} -{{- end }} -{{- if $setHTTPSScheme -}} -{{- $_ := set . "scheme" "https" }} -{{- end -}} -{{- if $useHTTPS -}} -{{- if (hasKey . "params") }} -{{- $_ := set (get . "params") "_scheme" (list "https") }} -{{- else }} -{{- $_ := set . "params" (dict "_scheme" (list "https")) }} -{{- end }} -{{- end }} -{{- if (hasKey . "tlsConfig") }} -{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} -{{- else }} -{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} -{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} -{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} -{{- end }} -{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} -{{- if (hasKey . "authorization") }} -{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} -{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} -{{- else }} -{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} -{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} -{{- end }} -{{- end }} -{{- end }} -{{- toYaml $endpoints }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml deleted file mode 100644 index a8e27c3735..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.client.name" . }} -{{- end }} -{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} -- nonResourceURLs: ["/metrics"] - verbs: ["get"] -{{- if .Values.clients.rbac.additionalRules }} -{{ toYaml .Values.clients.rbac.additionalRules }} -{{- end }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.client.name" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.client.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} ---- -{{- if .Values.clients.https.useServiceAccountCredentials }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: {{ template "pushProxy.client.serviceAccountTokenName" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - annotations: - kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} -{{- end }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - privileged: false - hostNetwork: true - hostIPC: false - hostPID: false - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} -{{- end }} - supplementalGroups: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - - min: 0 - max: 65535 - readOnlyRootFilesystem: false - volumes: - - 'secret' -{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - - 'emptyDir' - - 'hostPath' - allowedHostPaths: - - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - readOnly: true -{{- end }} -{{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-clients.yaml deleted file mode 100644 index e8fcfb3883..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-clients.yaml +++ /dev/null @@ -1,157 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.clients }}{{- if .Values.clients.enabled }} -apiVersion: apps/v1 -{{- if .Values.clients.deployment.enabled }} -kind: Deployment -{{- else }} -kind: DaemonSet -{{- end }} -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} - pushprox-exporter: "client" -spec: - {{- if .Values.clients.deployment.enabled }} - replicas: {{ .Values.clients.deployment.replicas }} - {{- end }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.client.labels" . | nindent 8 }} - spec: - {{- if .Values.clients.affinity }} - affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} - {{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.clients.nodeSelector }} -{{ toYaml .Values.clients.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.clients.tolerations }} -{{ toYaml .Values.clients.tolerations | indent 8 }} -{{- end }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - serviceAccountName: {{ template "pushProxy.client.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-client - image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} - command: - {{- range .Values.clients.command }} - - {{ . | quote }} - {{- end }} - args: - - --fqdn=$(HOST_IP) - - --proxy-url=$(PROXY_URL) - {{- if .Values.clients.metrics.enabled }} - - --metrics-addr=$(PORT) - {{- end }} - - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} - {{- if .Values.clients.useLocalhost }} - - --use-localhost - {{- end }} - {{- if .Values.clients.https.enabled }} - {{- if .Values.clients.https.insecureSkipVerify }} - - --insecure-skip-verify - {{- end }} - {{- if .Values.clients.https.useServiceAccountCredentials }} - - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - {{- end }} - {{- if .Values.clients.https.certDir }} - - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem - - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem - - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem - {{- end }} - {{- end }} - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.clients.metrics.enabled }} - - name: PORT - value: :{{ .Values.clients.port }} - {{- end }} - - name: PROXY_URL - value: {{ template "pushProxy.proxyUrl" . }} - securityContext: - runAsNonRoot: true - runAsUser: 1000 - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - volumeMounts: - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - {{- end }} - {{- if .Values.clients.resources }} - resources: {{ toYaml .Values.clients.resources | nindent 10 }} - {{- end }} - {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} - initContainers: - - name: copy-certs - image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} - command: - - sh - - -c - - | - echo "Searching for files to copy within the source volume" - echo "cert: ${CERT_FILE_NAME}" - echo "key: ${KEY_FILE_NAME}" - echo "cacert: ${CACERT_FILE_NAME}" - - CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) - KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) - CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) - - test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 - test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 - test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 - - echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" - cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 - chmod 444 $CERT_FILE_TARGET || exit 1 - - echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" - cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 - chmod 444 $KEY_FILE_TARGET || exit 1 - - echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" - cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 - chmod 444 $CACERT_FILE_TARGET || exit 1 - env: - - name: CERT_FILE_NAME - value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} - - name: KEY_FILE_NAME - value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} - - name: CACERT_FILE_NAME - value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} - - name: CERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy.pem - - name: KEY_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-key.pem - - name: CACERT_FILE_TARGET - value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem - securityContext: - runAsNonRoot: false -{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} - seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} -{{- end }} - volumeMounts: - - name: metrics-cert-dir-source - mountPath: /etc/source - readOnly: true - - name: metrics-cert-dir - mountPath: /etc/ssl/push-proxy - volumes: - - name: metrics-cert-dir-source - hostPath: - path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} - - name: metrics-cert-dir - emptyDir: {} - {{- end }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml deleted file mode 100644 index eefe609058..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -rules: -{{- if .Values.global.cattle.psp.enabled }} -- apiGroups: ['policy'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "pushProxy.proxy.name" . }} -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "pushProxy.proxy.name" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "pushProxy.proxy.name" . }} -subjects: - - kind: ServiceAccount - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} ---- -{{- if .Values.global.cattle.psp.enabled }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ include "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - privileged: false - 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 - volumes: - - 'secret' -{{- end }}{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy.yaml deleted file mode 100644 index 723bbd6c00..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} - pushprox-exporter: "proxy" -spec: - selector: - matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} - template: - metadata: - labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} - spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- if .Values.proxy.nodeSelector }} -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- if .Values.proxy.tolerations }} -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - serviceAccountName: {{ template "pushProxy.proxy.name" . }} - {{- if .Values.global.imagePullSecretName }} - imagePullSecrets: - - name: {{ .Values.global.imagePullSecretName }} - {{- end }} - containers: - - name: pushprox-proxy - image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} - command: - {{- range .Values.proxy.command }} - - {{ . | quote }} - {{- end }} - {{- if .Values.proxy.resources }} - resources: {{ toYaml .Values.proxy.resources | nindent 10 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.proxy.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -spec: - ports: - - name: pp-proxy - port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} - protocol: TCP - targetPort: {{ .Values.proxy.port }} - selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml deleted file mode 100644 index 67eb2216b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -{{- template "applyKubeVersionOverrides" . -}} -{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "pushprox.serviceMonitor.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} -spec: - endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} - jobLabel: component - podTargetLabels: - - component - - pushprox-exporter - namespaceSelector: - matchNames: - - {{ template "pushprox.namespace" . }} - selector: - matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} ---- -{{- $selector := "" }} -{{- if not (kindIs "invalid" .Values.service) }} -{{- if not (kindIs "invalid" .Values.service.selector) }} -{{ if .Values.service.selector }} -{{- if .Values.clients.enabled }} -{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} -{{- end }} -{{- $selector = (toYaml .Values.service.selector) }} -{{- end }} -{{- end }} -{{- end }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "pushProxy.client.name" . }} - namespace: {{ template "pushprox.namespace" . }} - labels: {{ include "pushProxy.client.labels" . | nindent 4 }} -spec: - ports: - - name: metrics - port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} - protocol: TCP - targetPort: {{ .Values.metricsPort }} - selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/validate-install-crd.yaml deleted file mode 100644 index 16abc2fa83..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/validate-install-crd.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/validate-psp-install.yaml deleted file mode 100644 index a30c59d3b7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/templates/validate-psp-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- if .Values.global.cattle.psp.enabled }} -#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} -#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} -#{{- end }} -#{{- end }} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/values.yaml deleted file mode 100644 index 1e076041b3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/rkeScheduler/values.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Default values for rancher-pushprox. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Default image containing both the proxy and the client was generated from the following Dockerfile -# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 - -# Configuration - -global: - cattle: - psp: - enabled: false - systemDefaultRegistry: "" - seLinux: - enabled: false - -# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. -# -# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches -# any of the semver constraints provided as keys on the map. -# -# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. -# -# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. -# -# Notes: -# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 -# - On running a helm install --dry-run, the correct kubeVersion should be chosen. -kubeVersionOverrides: [] -# - constraint: "< 1.21" -# values: -# metricsPort: 10252 -# clients: -# https: -# enabled: false -# insecureSkipVerify: false -# useServiceAccountCredentials: false - -namespaceOverride: "" - -# The component that is being monitored (i.e. etcd) -component: "component" - -# The port containing the metrics that need to be scraped -metricsPort: 2739 - -# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint -serviceMonitor: - enabled: true - # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec - # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint - # By default, proxyUrl and params._scheme will be overridden based on other values - endpoints: - - port: metrics - -# Configure Service that grabs scrape targets -service: - # The selector that is used to populate the Service's Endpoints object. - # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, - # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment - selector: {} - -clients: - enabled: true - # The port which the PushProx client will post PushProx metrics to - port: 9369 - # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} - # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null - proxyUrl: "" - # If set to true, the client will forward any requests from the host IP to 127.0.0.1 - # It will only allow proxy requests to the metricsPort specified - useLocalhost: false - # Configuration for accessing metrics via HTTPS - https: - # Does the client require https to access the metrics? - enabled: false - # Does the client require requests be sent to http or https? - forceHTTPSScheme: false - # If set to true, the client will create a service account with adequate permissions and set a flag - # on the client to use the service account token provided by it to make authorized scrape requests - useServiceAccountCredentials: false - # Configuration for authentication to metrics via https endpoint - authenticationMethod: - # Reads token from defined file in container - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenFile: - enabled: false - bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" - # Reads token from defined secret in namespace - # This function is deprecated in the prometheus operator api and may be removed in a future version - bearerTokenSecret: - enabled: false - # Reads token from defined secret in namespace - authorization: - enabled: false - type: "bearer" - credentials: - key: "token" - optional: false - # If set to true, the client will disable SSL security checks - insecureSkipVerify: false - # Directory on host where necessary TLS cert and key to scrape metrics can be found - certDir: "" - # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings - certFile: "" - keyFile: "" - caCertFile: "" - # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. - # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. - seLinuxOptions: {} - - metrics: - # Whether the client should publish PushProx client-specific metrics to .Values.clients.port - enabled: false - - rbac: - # Additional permissions to provide to the ServiceAccount bound to the client - # This can be used to provide additional permissions for the client to scrape metrics from the k8s API - # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true - additionalRules: [] - - # Resource limits - resources: {} - - # Options to select all nodes to deploy client DaemonSet on - nodeSelector: {} - tolerations: [] - affinity: {} - - image: - repository: rancher/pushprox-client - tag: v0.1.3-rancher2-client - command: ["pushprox-client"] - - copyCertsImage: - repository: rancher/mirrored-library-busybox - tag: 1.31.1 - - # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. - # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in - # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. - # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, - # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. - # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will - # be responsible for upgrading this chart accordingly to the right number of replicas. - deployment: - enabled: false - replicas: 0 - -proxy: - enabled: true - # The port through which PushProx clients will communicate to the proxy - port: 8080 - - # Resource limits - resources: {} - - # Options to select a node to run a single proxy deployment on - nodeSelector: {} - tolerations: [] - - image: - repository: rancher/pushprox-proxy - tag: v0.1.3-rancher2-proxy - command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/.helmignore b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/.helmignore deleted file mode 100644 index f0c1319444..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/.helmignore +++ /dev/null @@ -1,21 +0,0 @@ -# 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/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/Chart.yaml deleted file mode 100644 index 784bb0ec7e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/Chart.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v2 -appVersion: 0.25.1 -description: A Helm chart for prometheus windows-exporter -home: https://github.com/prometheus-community/windows_exporter/ -keywords: -- windows-exporter -- windows -- prometheus -- exporter -maintainers: -- email: github@jkroepke.de - name: jkroepke -name: windowsExporter -sources: -- https://github.com/prometheus-community/windows_exporter/ -type: application -version: 0.3.1 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/README.md b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/README.md deleted file mode 100644 index 1da1c64e12..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Prometheus `Windows Exporter` - -Prometheus exporter for hardware and OS metrics exposed by Windows kernels, written in Go with pluggable metric collectors. - -This chart bootstraps a prometheus [`Windows Exporter`](http://github.com/prometheus-community/windows_exporter) daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. - -## Get Repository Info - -```console -helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -helm repo update -``` - -_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ - -## Install Chart - -```console -helm install [RELEASE_NAME] prometheus-community/prometheus-windows-exporter -``` - -_See [configuration](#configuring) below._ - -_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ - -## Uninstall 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._ - -## Configuring - -See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: - -```console -helm show values prometheus-community/prometheus-windows-exporter -``` diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/scripts/configure-firewall.ps1 b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/scripts/configure-firewall.ps1 deleted file mode 100644 index 9cbed7112d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/scripts/configure-firewall.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -$ErrorActionPreference = 'Continue' - -function CheckFirewallRuleError { - # We hit an error. This can happen for a number of reasons, including if the rule already exists - if ($error[0]) { - if (($error[0].Exception.NativeErrorCode) -and ($error[0].Exception.NativeErrorCode.ToString() -eq "AlreadyExists")) { - # Previous versions of monitoring may have already created this Firewall Rule - # Because of this, if the rule alreadys exists there is no need to delete and recreate it. - Write-Host "Detected Existing Firewall Rule, Nothing To Do" - } else { - Write-Host "Error Encountered Setting Up Required Firewall Rule" - $error[0].Exception - exit 1 - } - } -} - -Write-Host "Attempting To Configure Firewall Rules For Ports 9796, 10250" - -# This is the exact same firewall rule that has historically been created by rancher-wins -# https://github.com/rancher/wins/blob/91f670c47f19c6d9fe97d8f66a695d3081ad994f/pkg/apis/process_service_mgmt.go#L149 -New-NetFirewallRule -DisplayName rancher-wins-windows-exporter-TCP-9796 -Name rancher-wins-windows-exporter-TCP-9796 -Action Allow -Protocol TCP -LocalPort 9796 -Enabled True -PolicyStore ActiveStore -CheckFirewallRuleError -Write-Host "Windows Node Exporter Firewall Rule Successfully Created" - -# This rule is required in order to have the Rancher UI display node metrics in the 'Nodes' tab of the cluster explorer -New-NetFirewallRule -DisplayName rancher-wins-windows-exporter-TCP-10250 -Name rancher-wins-windows-exporter-TCP-10250 -Action Allow -Protocol TCP -LocalPort 10250 -Enabled True -PolicyStore ActiveStore -CheckFirewallRuleError -Write-Host "Windows Prometheus Metrics Firewall Rule Successfully Created" - -Write-Host "All Firewall Rules Successfully Configured" diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/_helpers.tpl deleted file mode 100644 index c9a5d6db8c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/_helpers.tpl +++ /dev/null @@ -1,216 +0,0 @@ -{{/* -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. -The components in this chart create additional resources that expand the longest created name strings. -The longest name that gets created adds and extra 37 characters, so truncation should be 63-35=26. -*/}} -{{- define "prometheus-windows-exporter.fullname" -}} -{{ printf "%s-windows-exporter" .Release.Name }} -{{- end -}} - -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -{{- define "windowsExporter.renamedMetricsRelabeling" -}} -{{- range $original, $new := (include "windowsExporter.renamedMetrics" . | fromJson) -}} -- sourceLabels: [__name__] - regex: {{ $original }} - replacement: '{{ $new }}' - targetLabel: __name__ -{{ end -}} -{{- end -}} - -{{- define "windowsExporter.labels" -}} -k8s-app: {{ template "prometheus-windows-exporter.fullname" . }} -release: {{ .Release.Name }} -component: "windows-exporter" -provider: kubernetes -{{- end -}} - -{{- define "windowsExporter.renamedMetrics" -}} -{{- $renamed := dict -}} -{{/* v0.15.0 */}} -{{- $_ := set $renamed "windows_mssql_transactions_active_total" "windows_mssql_transactions_active" -}} -{{/* v0.16.0 */}} -{{- $_ := set $renamed "windows_adfs_ad_login_connection_failures" "windows_adfs_ad_login_connection_failures_total" -}} -{{- $_ := set $renamed "windows_adfs_certificate_authentications" "windows_adfs_certificate_authentications_total" -}} -{{- $_ := set $renamed "windows_adfs_device_authentications" "windows_adfs_device_authentications_total" -}} -{{- $_ := set $renamed "windows_adfs_extranet_account_lockouts" "windows_adfs_extranet_account_lockouts_total" -}} -{{- $_ := set $renamed "windows_adfs_federated_authentications" "windows_adfs_federated_authentications_total" -}} -{{- $_ := set $renamed "windows_adfs_passport_authentications" "windows_adfs_passport_authentications_total" -}} -{{- $_ := set $renamed "windows_adfs_password_change_failed" "windows_adfs_password_change_failed_total" -}} -{{- $_ := set $renamed "windows_adfs_password_change_succeeded" "windows_adfs_password_change_succeeded_total" -}} -{{- $_ := set $renamed "windows_adfs_token_requests" "windows_adfs_token_requests_total" -}} -{{- $_ := set $renamed "windows_adfs_windows_integrated_authentications" "windows_adfs_windows_integrated_authentications_total" -}} -{{- $_ := set $renamed "windows_net_packets_outbound_errors" "windows_net_packets_outbound_errors_total" -}} -{{- $_ := set $renamed "windows_net_packets_received_discarded" "windows_net_packets_received_discarded_total" -}} -{{- $_ := set $renamed "windows_net_packets_received_errors" "windows_net_packets_received_errors_total" -}} -{{- $_ := set $renamed "windows_net_packets_received_total" "windows_net_packets_received_total_total" -}} -{{- $_ := set $renamed "windows_net_packets_received_unknown" "windows_net_packets_received_unknown_total" -}} -{{- $_ := set $renamed "windows_dns_memory_used_bytes_total" "windows_dns_memory_used_bytes" -}} -{{- $renamed | toJson -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "prometheus-windows-exporter.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "prometheus-windows-exporter.labels" -}} -helm.sh/chart: {{ include "prometheus-windows-exporter.chart" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -app.kubernetes.io/component: metrics -app.kubernetes.io/part-of: {{ include "prometheus-windows-exporter.name" . }} -{{ include "prometheus-windows-exporter.selectorLabels" . }} -{{- with .Chart.AppVersion }} -app.kubernetes.io/version: {{ . | quote }} -{{- end }} -{{- with .Values.podLabels }} -{{ toYaml . }} -{{- end }} -{{- if .Values.releaseLabel }} -release: {{ .Release.Name }} -{{- end }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "prometheus-windows-exporter.selectorLabels" -}} -app.kubernetes.io/name: {{ include "prometheus-windows-exporter.fullname" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - - -{{/* -Create the name of the service account to use -*/}} -{{- define "prometheus-windows-exporter.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "prometheus-windows-exporter.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} - -{{/* -The image to use -*/}} -{{- define "prometheus-windows-exporter.image" -}} -{{- if .Values.image.sha }} -{{- fail "image.sha forbidden. Use image.digest instead" }} -{{- else if .Values.image.digest }} -{{- if .Values.global.cattle.systemDefaultRegistry }} -{{- printf "%s/%s:%s@%s" .Values.global.cattle.systemDefaultRegistry .Values.image.repository (default .Chart.AppVersion .Values.image.tag) .Values.image.digest }} -{{- else }} -{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default .Chart.AppVersion .Values.image.tag) .Values.image.digest }} -{{- end }} -{{- else }} -{{- if .Values.global.cattle.systemDefaultRegistry }} -{{- printf "%s/%s:%s" .Values.global.cattle.systemDefaultRegistry .Values.image.repository (default .Chart.AppVersion .Values.image.tag) }} -{{- else }} -{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default .Chart.AppVersion .Values.image.tag) }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Allow the release namespace to be overridden for multi-namespace deployments in combined charts -*/}} -{{- define "prometheus-windows-exporter.namespace" -}} -{{- if .Values.namespaceOverride }} -{{- .Values.namespaceOverride }} -{{- else }} -{{- .Release.Namespace }} -{{- end }} -{{- end }} - -{{/* -Create the namespace name of the service monitor -*/}} -{{- define "prometheus-windows-exporter.monitor-namespace" -}} -{{- if .Values.namespaceOverride }} -{{- .Values.namespaceOverride }} -{{- else }} -{{- if .Values.prometheus.monitor.namespace }} -{{- .Values.prometheus.monitor.namespace }} -{{- else }} -{{- .Release.Namespace }} -{{- end }} -{{- end }} -{{- end }} - -{{/* Sets default scrape limits for servicemonitor */}} -{{- define "servicemonitor.scrapeLimits" -}} -{{- with .sampleLimit }} -sampleLimit: {{ . }} -{{- end }} -{{- with .targetLimit }} -targetLimit: {{ . }} -{{- end }} -{{- with .labelLimit }} -labelLimit: {{ . }} -{{- end }} -{{- with .labelNameLengthLimit }} -labelNameLengthLimit: {{ . }} -{{- end }} -{{- with .labelValueLengthLimit }} -labelValueLengthLimit: {{ . }} -{{- end }} -{{- end }} - -{{/* -Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) -*/}} -{{- define "prometheus-windows-exporter.imagePullSecrets" -}} -{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} - {{- if eq (typeOf .) "map[string]interface {}" }} -- {{ toYaml . | trim }} - {{- else }} -- name: {{ . }} - {{- end }} -{{- end }} -{{- end -}} - -{{/* -Create the namespace name of the pod monitor -*/}} -{{- define "prometheus-windows-exporter.podmonitor-namespace" -}} -{{- if .Values.namespaceOverride }} -{{- .Values.namespaceOverride }} -{{- else }} -{{- if .Values.prometheus.podMonitor.namespace }} -{{- .Values.prometheus.podMonitor.namespace }} -{{- else }} -{{- .Release.Namespace }} -{{- end }} -{{- end }} -{{- end }} - -{{/* Sets default scrape limits for podmonitor */}} -{{- define "podmonitor.scrapeLimits" -}} -{{- with .sampleLimit }} -sampleLimit: {{ . }} -{{- end }} -{{- with .targetLimit }} -targetLimit: {{ . }} -{{- end }} -{{- with .labelLimit }} -labelLimit: {{ . }} -{{- end }} -{{- with .labelNameLengthLimit }} -labelNameLengthLimit: {{ . }} -{{- end }} -{{- with .labelValueLengthLimit }} -labelValueLengthLimit: {{ . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/config.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/config.yaml deleted file mode 100644 index 25f1fa69c2..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/config.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "prometheus-windows-exporter.fullname" . }} - namespace: {{ include "prometheus-windows-exporter.namespace" . }} - labels: - {{- include "windowsExporter.labels" $ | nindent 4 }} - {{- with .Values.service.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -data: - config.yml: | - {{- .Values.config | nindent 4 }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/daemonset.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/daemonset.yaml deleted file mode 100644 index be7feb3ed1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/daemonset.yaml +++ /dev/null @@ -1,200 +0,0 @@ -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: {{ include "prometheus-windows-exporter.fullname" . }} - namespace: {{ include "prometheus-windows-exporter.namespace" . }} - labels: - {{- include "windowsExporter.labels" . | nindent 4 }} - {{- with .Values.daemonsetAnnotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: - {{- include "windowsExporter.labels" . | nindent 6 }} - {{- with .Values.updateStrategy }} - updateStrategy: - {{- toYaml . | nindent 4 }} - {{- end }} - template: - metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "windowsExporter.labels" . | nindent 8 }} - spec: - automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} - {{- with .Values.securityContext }} - securityContext: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.priorityClassName }} - priorityClassName: {{ . }} - {{- end }} - initContainers: - - name: configure-firewall - image: {{ include "prometheus-windows-exporter.image" . }} - command: - - C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe - args: ["-f", "scripts/configure-firewall.ps1"] - volumeMounts: - - mountPath: /scripts - name: exporter-scripts - {{- with .Values.extraInitContainers }} - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "prometheus-windows-exporter.fullname" . }} - containers: - - name: windows-exporter - image: {{ include "prometheus-windows-exporter.image" . }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - args: - - --config.file=%CONTAINER_SANDBOX_MOUNT_POINT%/config.yml - - --collector.textfile.directories=%CONTAINER_SANDBOX_MOUNT_POINT% - - --web.listen-address=:{{ .Values.service.port }} - {{- with .Values.extraArgs }} - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.securityContext }} - securityContext: - {{- toYaml . | nindent 12 }} - {{- end }} - env: - {{- range $key, $value := .Values.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - ports: - - name: http - containerPort: {{ .Values.service.port }} - hostPort: {{ .Values.service.port }} - protocol: TCP - livenessProbe: - failureThreshold: {{ .Values.livenessProbe.failureThreshold }} - httpGet: - httpHeaders: - {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} - - name: {{ $header.name }} - value: {{ $header.value }} - {{- end }} - path: / - port: {{ .Values.service.port }} - scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} - initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.livenessProbe.periodSeconds }} - successThreshold: {{ .Values.livenessProbe.successThreshold }} - timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} - readinessProbe: - failureThreshold: {{ .Values.readinessProbe.failureThreshold }} - httpGet: - httpHeaders: - {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} - - name: {{ $header.name }} - value: {{ $header.value }} - {{- end }} - path: / - port: {{ .Values.service.port }} - scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} - initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.readinessProbe.periodSeconds }} - successThreshold: {{ .Values.readinessProbe.successThreshold }} - timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} - {{- with .Values.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - volumeMounts: - - name: config - mountPath: /config.yml - subPath: config.yml - {{- range $_, $mount := .Values.extraHostVolumeMounts }} - - name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - readOnly: {{ $mount.readOnly }} - {{- end }} - {{- range $_, $mount := .Values.sidecarVolumeMount }} - - name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - readOnly: true - {{- end }} - {{- range $_, $mount := .Values.configmaps }} - - name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - {{- end }} - {{- range $_, $mount := .Values.secrets }} - - name: {{ .name }} - mountPath: {{ .mountPath }} - {{- end }} - {{- with .Values.sidecars }} - {{- toYaml . | nindent 8 }} - {{- if or .Values.sidecarVolumeMount .Values.sidecarHostVolumeMounts }} - volumeMounts: - {{- range $_, $mount := .Values.sidecarVolumeMount }} - - name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - readOnly: {{ $mount.readOnly }} - {{- end }} - {{- range $_, $mount := .Values.sidecarHostVolumeMounts }} - - name: {{ $mount.name }} - mountPath: {{ $mount.mountPath }} - readOnly: {{ $mount.readOnly }} - {{- end }} - {{- end }} - {{- end }} - {{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- include "prometheus-windows-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} - {{- end }} - hostNetwork: {{ .Values.hostNetwork }} - hostPID: {{ .Values.hostPID }} - {{- with .Values.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.dnsConfig }} - dnsConfig: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - volumes: - - name: exporter-scripts - configMap: - name: {{ include "prometheus-windows-exporter.fullname" . }}-scripts - - name: config - configMap: - name: {{ include "prometheus-windows-exporter.fullname" . }} - {{- range $_, $mount := .Values.extraHostVolumeMounts }} - - name: {{ $mount.name }} - hostPath: - path: {{ $mount.hostPath }} - {{- end }} - {{- range $_, $mount := .Values.sidecarVolumeMount }} - - name: {{ $mount.name }} - emptyDir: - medium: Memory - {{- end }} - {{- range $_, $mount := .Values.sidecarHostVolumeMounts }} - - name: {{ $mount.name }} - hostPath: - path: {{ $mount.hostPath }} - {{- end }} - {{- range $_, $mount := .Values.configmaps }} - - name: {{ $mount.name }} - configMap: - name: {{ $mount.name }} - {{- end }} - {{- range $_, $mount := .Values.secrets }} - - name: {{ $mount.name }} - secret: - secretName: {{ $mount.name }} - {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/podmonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/podmonitor.yaml deleted file mode 100644 index bbb6c39340..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/podmonitor.yaml +++ /dev/null @@ -1,91 +0,0 @@ -{{- if .Values.prometheus.podMonitor.enabled }} -apiVersion: {{ .Values.prometheus.podMonitor.apiVersion | default "monitoring.coreos.com/v1" }} -kind: PodMonitor -metadata: - name: {{ include "prometheus-windows-exporter.fullname" . }} - namespace: {{ include "prometheus-windows-exporter.podmonitor-namespace" . }} - labels: - {{- include "windowsExporter.labels" . | nindent 4 }} - {{- with .Values.prometheus.podMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.podMonitor.jobLabel }} - {{- include "podmonitor.scrapeLimits" .Values.prometheus.podMonitor | nindent 2 }} - selector: - matchLabels: - {{- with .Values.prometheus.podMonitor.selectorOverride }} - {{- toYaml . | nindent 6 }} - {{- else }} - {{- include "prometheus-windows-exporter.selectorLabels" . | nindent 6 }} - {{- end }} - namespaceSelector: - matchNames: - - {{ include "prometheus-windows-exporter.namespace" . }} - {{- with .Values.prometheus.podMonitor.attachMetadata }} - attachMetadata: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.podTargetLabels }} - podTargetLabels: - {{- toYaml . | nindent 4 }} - {{- end }} - podMetricsEndpoints: - - port: {{ .Values.service.portName }} - {{- with .Values.prometheus.podMonitor.scheme }} - scheme: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.path }} - path: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.basicAuth }} - basicAuth: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.bearerTokenSecret }} - bearerTokenSecret: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.tlsConfig }} - tlsConfig: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.authorization }} - authorization: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.oauth2 }} - oauth2: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.proxyUrl }} - proxyUrl: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.interval }} - interval: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.honorTimestamps }} - honorTimestamps: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.honorLabels }} - honorLabels: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.scrapeTimeout }} - scrapeTimeout: {{ . }} - {{- end }} - {{- with .Values.prometheus.podMonitor.relabelings }} - relabelings: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.podMonitor.metricRelabelings }} - metricRelabelings: - {{- toYaml . | nindent 8 }} - {{- end }} - enableHttp2: {{ default false .Values.prometheus.podMonitor.enableHttp2 }} - filterRunning: {{ default true .Values.prometheus.podMonitor.filterRunning }} - followRedirects: {{ default false .Values.prometheus.podMonitor.followRedirects }} - {{- with .Values.prometheus.podMonitor.params }} - params: - {{- toYaml . | nindent 8 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/scriptConfig.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/scriptConfig.yaml deleted file mode 100644 index f514c8161a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/scriptConfig.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "prometheus-windows-exporter.fullname" . }}-scripts - namespace: {{ include "prometheus-windows-exporter.namespace" . }} - labels: - {{- include "windowsExporter.labels" $ | nindent 4 }} - {{- with .Values.service.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -data: -{{ (.Files.Glob "scripts/*").AsConfig | indent 2 }} - diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/service.yaml deleted file mode 100644 index 267b796f63..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/service.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "prometheus-windows-exporter.fullname" . }} - namespace: {{ include "prometheus-windows-exporter.namespace" . }} - labels: - {{- include "windowsExporter.labels" $ | nindent 4 }} - {{- if or .Values.prometheus.monitor.enabled .Values.prometheus.podMonitor.enabled }} - {{- with .Values.service.annotations }} - annotations: - {{- unset . "prometheus.io/scrape" | toYaml | nindent 4 }} - {{- end }} - {{- else }} - annotations: - prometheus.io/scrape: "true" - {{- with .Values.service.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- end }} -spec: - type: {{ .Values.service.type }} - ports: - - port: {{ .Values.service.port }} - {{- if ( and (eq .Values.service.type "NodePort" ) (not (empty .Values.service.nodePort)) ) }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} - targetPort: {{ .Values.service.port }} - protocol: TCP - appProtocol: http - name: {{ .Values.service.portName }} - selector: - {{- include "windowsExporter.labels" . | nindent 4 }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/serviceaccount.yaml deleted file mode 100644 index 14c1c46807..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/serviceaccount.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.rbac.create .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "prometheus-windows-exporter.serviceAccountName" . }} - namespace: {{ include "prometheus-windows-exporter.namespace" . }} - labels: - {{- include "windowsExporter.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} -imagePullSecrets: - {{- include "prometheus-windows-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} -{{- end }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/servicemonitor.yaml deleted file mode 100644 index 2effc07758..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/templates/servicemonitor.yaml +++ /dev/null @@ -1,75 +0,0 @@ -{{- if .Values.prometheus.monitor.enabled }} -apiVersion: {{ .Values.prometheus.monitor.apiVersion | default "monitoring.coreos.com/v1" }} -kind: ServiceMonitor -metadata: - name: {{ include "prometheus-windows-exporter.fullname" . }} - namespace: {{ include "prometheus-windows-exporter.monitor-namespace" . }} - labels: - {{- include "windowsExporter.labels" . | nindent 4 }} - {{- with .Values.prometheus.monitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} - {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | nindent 2 }} - {{- with .Values.prometheus.monitor.podTargetLabels }} - podTargetLabels: - {{- toYaml . | nindent 4 }} - {{- end }} - selector: - matchLabels: - {{- with .Values.prometheus.monitor.selectorOverride }} - {{- toYaml . | nindent 6 }} - {{- else }} - {{- include "windowsExporter.labels" . | nindent 6 }} - {{- end }} - {{- with .Values.prometheus.monitor.attachMetadata }} - attachMetadata: - {{- toYaml . | nindent 4 }} - {{- end }} - endpoints: - - port: {{ .Values.service.portName }} - scheme: {{ .Values.prometheus.monitor.scheme }} - {{- with .Values.prometheus.monitor.basicAuth }} - basicAuth: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.monitor.bearerTokenFile }} - bearerTokenFile: {{ . }} - {{- end }} - {{- with .Values.prometheus.monitor.tlsConfig }} - tlsConfig: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheus.monitor.proxyUrl }} - proxyUrl: {{ . }} - {{- end }} - {{- with .Values.prometheus.monitor.interval }} - interval: {{ . }} - {{- end }} - {{- with .Values.prometheus.monitor.scrapeTimeout }} - scrapeTimeout: {{ . }} - {{- end }} - metricRelabelings: -{{- include "windowsExporter.renamedMetricsRelabeling" . | nindent 6 -}} - - sourceLabels: [__name__] - regex: 'wmi_(.*)' - replacement: 'windows_$1' - targetLabel: __name__ - - sourceLabels: [volume, nic] - regex: (.*);(.*) - separator: '' - targetLabel: device - action: replace - replacement: $1$2 - - sourceLabels: [__name__] - regex: windows_cs_logical_processors - replacement: 'system' - targetLabel: mode - relabelings: - - separator: ':' - sourceLabels: - - __meta_kubernetes_pod_host_ip - - __meta_kubernetes_pod_container_port_number - targetLabel: instance -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/values.yaml deleted file mode 100644 index 04569505d6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/charts/windowsExporter/values.yaml +++ /dev/null @@ -1,366 +0,0 @@ -# Default values for prometheus-windows-exporter. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -image: - registry: docker.io - repository: rancher/mirrored-prometheus-windows-exporter - # Overrides the image tag whose default is {{ printf "v%s" .Chart.AppVersion }} - tag: "0.25.1" - pullPolicy: IfNotPresent - digest: "" - -config: |- - collectors: - enabled: '[defaults],tcp,memory,container' - -imagePullSecrets: [] -# - name: "image-pull-secret" -nameOverride: "" -fullnameOverride: "" - -global: - # To help compatibility with other charts which use global.imagePullSecrets. - # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). - # global: - # imagePullSecrets: - # - name: pullSecret1 - # - name: pullSecret2 - # or - # global: - # imagePullSecrets: - # - pullSecret1 - # - pullSecret2 - imagePullSecrets: [] - cattle: - systemDefaultRegistry: "" - -service: - type: ClusterIP - port: 9796 - nodePort: - portName: windows-metrics - annotations: {} - -# Additional environment variables that will be passed to the daemonset -env: {} -## env: -## VARIABLE: value - -prometheus: - monitor: - enabled: true - additionalLabels: {} - namespace: "" - - jobLabel: "component" - - # List of pod labels to add to windows exporter metrics - # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor - podTargetLabels: ["component"] - - scheme: http - basicAuth: {} - bearerTokenFile: - tlsConfig: {} - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## Override serviceMonitor selector - ## - selectorOverride: {} - - ## Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. - ## - attachMetadata: - node: false - - relabelings: [] - metricRelabelings: [] - interval: "" - scrapeTimeout: 10s - ## prometheus.monitor.apiVersion ApiVersion for the serviceMonitor Resource(defaults to "monitoring.coreos.com/v1") - apiVersion: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - # PodMonitor defines monitoring for a set of pods. - # ref. https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor - # Using a PodMonitor may be preferred in some environments where there is very large number - # of Windows Exporter endpoints (1000+) behind a single service. - # The PodMonitor is disabled by default. When switching from ServiceMonitor to PodMonitor, - # the time series resulting from the configuration through PodMonitor may have different labels. - # For instance, there will not be the service label any longer which might - # affect PromQL queries selecting that label. - podMonitor: - enabled: false - # Namespace in which to deploy the pod monitor. Defaults to the release namespace. - namespace: "" - # Additional labels, e.g. setting a label for pod monitor selector as set in prometheus - additionalLabels: {} - # release: kube-prometheus-stack - # PodTargetLabels transfers labels of the Kubernetes Pod onto the target. - podTargetLabels: [] - # apiVersion defaults to monitoring.coreos.com/v1. - apiVersion: "" - # Override pod selector to select pod objects. - selectorOverride: {} - # Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. - attachMetadata: - node: false - # The label to use to retrieve the job name from. Defaults to label app.kubernetes.io/name. - jobLabel: "" - - # Scheme/protocol to use for scraping. - scheme: "http" - # Path to scrape metrics at. - path: "/metrics" - - # BasicAuth allow an endpoint to authenticate over basic authentication. - # More info: https://prometheus.io/docs/operating/configuration/#endpoint - basicAuth: {} - # Secret to mount to read bearer token for scraping targets. - # The secret needs to be in the same namespace as the pod monitor and accessible by the Prometheus Operator. - # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secretkeyselector-v1-core - bearerTokenSecret: {} - # TLS configuration to use when scraping the endpoint. - tlsConfig: {} - # Authorization section for this endpoint. - # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.SafeAuthorization - authorization: {} - # OAuth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer. - # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.OAuth2 - oauth2: {} - - # ProxyURL eg http://proxyserver:2195. Directs scrapes through proxy to this endpoint. - proxyUrl: "" - # Interval at which endpoints should be scraped. If not specified Prometheus’ global scrape interval is used. - interval: "" - # Timeout after which the scrape is ended. If not specified, the Prometheus global scrape interval is used. - scrapeTimeout: "" - # HonorTimestamps controls whether Prometheus respects the timestamps present in scraped data. - honorTimestamps: true - # HonorLabels chooses the metric’s labels on collisions with target labels. - honorLabels: true - # Whether to enable HTTP2. Default false. - enableHttp2: "" - # Drop pods that are not running. (Failed, Succeeded). - # Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase - filterRunning: "" - # FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. Default false. - followRedirects: "" - # Optional HTTP URL parameters - params: {} - - # RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds - # relabelings for a few standard Kubernetes fields. The original scrape job’s name - # is available via the __tmp_prometheus_job_name label. - # More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config - relabelings: [] - # MetricRelabelConfigs to apply to samples before ingestion. - metricRelabelings: [] - - # SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - sampleLimit: 0 - # TargetLimit defines a limit on the number of scraped targets that will be accepted. - targetLimit: 0 - # Per-scrape limit on number of labels that will be accepted for a sample. - # Only valid in Prometheus versions 2.27.0 and newer. - labelLimit: 0 - # Per-scrape limit on length of labels name that will be accepted for a sample. - # Only valid in Prometheus versions 2.27.0 and newer. - labelNameLengthLimit: 0 - # Per-scrape limit on length of labels value that will be accepted for a sample. - # Only valid in Prometheus versions 2.27.0 and newer. - labelValueLengthLimit: 0 - -## Customize the updateStrategy if set -updateStrategy: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 1 - -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: 200m - # memory: 50Mi - # requests: - # cpu: 100m -# memory: 30Mi - -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: {} - imagePullSecrets: [] - automountServiceAccountToken: false - -securityContext: - windowsOptions: - hostProcess: true - runAsUserName: "NT AUTHORITY\\system" - -rbac: - ## If true, create & use RBAC resources - ## - create: true - -# Expose the service to the host network -hostNetwork: true - -# Share the host process ID namespace -hostPID: true - -## Assign a group of affinity scheduling rules -## -affinity: {} -# nodeAffinity: -# requiredDuringSchedulingIgnoredDuringExecution: -# nodeSelectorTerms: -# - matchFields: -# - key: metadata.name -# operator: In -# values: -# - target-host-name - -# Annotations to be added to windows exporter pods -podAnnotations: - # Fix for very slow GKE cluster upgrades - cluster-autoscaler.kubernetes.io/safe-to-evict: "true" - -# Extra labels to be added to windows exporter pods -podLabels: {} - -# Annotations to be added to windows exporter daemonset -daemonsetAnnotations: {} - -## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box -releaseLabel: false - -# Custom DNS configuration to be added to prometheus-windows-exporter pods -dnsConfig: {} -# nameservers: -# - 1.2.3.4 -# searches: -# - ns1.svc.cluster-domain.example -# - my.dns.search.suffix -# options: -# - name: ndots -# value: "2" -# - name: edns0 - -## Assign a nodeSelector if operating a hybrid cluster -## -nodeSelector: - kubernetes.io/os: windows - # kubernetes.io/arch: amd64 - -tolerations: - - effect: NoSchedule - operator: Exists - -## Assign a PriorityClassName to pods if set -# priorityClassName: "" - -## Additional container arguments -## -extraArgs: [] -# - --collector.service.services-where -# - "Name LIKE 'sql%'" - -## Additional mounts from the host to windows-exporter container -## -extraHostVolumeMounts: [] -# - name: -# hostPath: -# mountPath: -# readOnly: true|false - -## Additional configmaps to be mounted. -## -configmaps: [] -# - name: -# mountPath: -secrets: [] -# - name: -# mountPath: -## Override the deployment namespace -## -namespaceOverride: "" - -## Additional containers for export metrics to text file -## -sidecars: [] -## - name: nvidia-dcgm-exporter -## image: nvidia/dcgm-exporter:1.4.3 - -## Volume for sidecar containers -## -sidecarVolumeMount: [] -## - name: collector-textfiles -## mountPath: /run/prometheus -## readOnly: false - -## Additional mounts from the host to sidecar containers -## -sidecarHostVolumeMounts: [] -# - name: -# hostPath: -# mountPath: -# readOnly: true|false -# mountPropagation: None|HostToContainer|Bidirectional - -## Additional InitContainers to initialize the pod -## -extraInitContainers: [] - -## Liveness probe -## -livenessProbe: - failureThreshold: 3 - httpGet: - httpHeaders: [] - scheme: http - initialDelaySeconds: 0 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - -## Readiness probe -## -readinessProbe: - failureThreshold: 3 - httpGet: - httpHeaders: [] - scheme: http - initialDelaySeconds: 0 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/ingress-nginx/nginx.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/ingress-nginx/nginx.json deleted file mode 100644 index 565352235a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/ingress-nginx/nginx.json +++ /dev/null @@ -1,1445 +0,0 @@ -{ - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - }, - { - "datasource": "$datasource", - "enable": true, - "expr": "sum(changes(nginx_ingress_controller_config_last_reload_successful_timestamp_seconds{instance!=\"unknown\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[30s])) by (controller_class)", - "hide": false, - "iconColor": "rgba(255, 96, 96, 1)", - "limit": 100, - "name": "Config Reloads", - "showIn": 0, - "step": "30s", - "tagKeys": "controller_class", - "tags": [], - "titleFormat": "Config Reloaded", - "type": "tags" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "iteration": 1534359654832, - "links": [], - "panels": [ - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$datasource", - "format": "ops", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 0, - "y": 0 - }, - "id": 20, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": true, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "round(sum(irate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[2m])), 0.001)", - "format": "time_series", - "intervalFactor": 1, - "refId": "A", - "step": 4 - } - ], - "thresholds": "", - "title": "Controller Request Volume", - "transparent": false, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$datasource", - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 6, - "y": 0 - }, - "id": 82, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": true, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(avg_over_time(nginx_ingress_controller_nginx_process_connections{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",state=\"active\"}[2m]))", - "format": "time_series", - "instant": false, - "intervalFactor": 1, - "refId": "A", - "step": 4 - } - ], - "thresholds": "", - "title": "Controller Connections", - "transparent": false, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$datasource", - "format": "percentunit", - "gauge": { - "maxValue": 100, - "minValue": 80, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": false - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 12, - "y": 0 - }, - "id": 21, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": true, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",status!~\"[4-5].*\"}[2m])) / sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[2m]))", - "format": "time_series", - "intervalFactor": 1, - "refId": "A", - "step": 4 - } - ], - "thresholds": "95, 99, 99.5", - "title": "Controller Success Rate (non-4|5xx responses)", - "transparent": false, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$datasource", - "decimals": 0, - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 18, - "y": 0 - }, - "id": 81, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": true, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "avg(irate(nginx_ingress_controller_success{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[1m])) * 60", - "format": "time_series", - "instant": false, - "intervalFactor": 1, - "refId": "A", - "step": 4 - } - ], - "thresholds": "", - "title": "Config Reloads", - "transparent": false, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "total" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$datasource", - "decimals": 0, - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 21, - "y": 0 - }, - "id": 83, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": true, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "count(nginx_ingress_controller_config_last_reload_successful{controller_pod=~\"$controller\",controller_namespace=~\"$namespace\"} == 0)", - "format": "time_series", - "instant": true, - "intervalFactor": 1, - "refId": "A", - "step": 4 - } - ], - "thresholds": "", - "title": "Last Config Failed", - "transparent": false, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": 2, - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 3 - }, - "height": "200px", - "id": 86, - "isNew": true, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideEmpty": false, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": 300, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "repeatDirection": "h", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "round(sum(irate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress), 0.001)", - "format": "time_series", - "hide": false, - "instant": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ ingress }}", - "metric": "network", - "refId": "A", - "step": 10 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Ingress Request Volume", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "transparent": false, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": false - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "max - istio-proxy": "#890f02", - "max - master": "#bf1b00", - "max - prometheus": "#bf1b00" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": 2, - "editable": false, - "error": false, - "fill": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 3 - }, - "id": 87, - "isNew": true, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideEmpty": true, - "hideZero": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": 300, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",ingress=~\"$ingress\",status!~\"[4-5].*\"}[2m])) by (ingress) / sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", - "format": "time_series", - "instant": false, - "interval": "10s", - "intervalFactor": 1, - "legendFormat": "{{ ingress }}", - "metric": "container_memory_usage:sort_desc", - "refId": "A", - "step": 10 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Ingress Success Rate (non-4|5xx responses)", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 1, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "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 - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": 2, - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 6, - "w": 8, - "x": 0, - "y": 10 - }, - "height": "200px", - "id": 32, - "isNew": true, - "legend": { - "alignAsTable": false, - "avg": true, - "current": true, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": 200, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum (irate (nginx_ingress_controller_request_size_sum{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m]))", - "format": "time_series", - "instant": false, - "interval": "10s", - "intervalFactor": 1, - "legendFormat": "Received", - "metric": "network", - "refId": "A", - "step": 10 - }, - { - "expr": "- sum (irate (nginx_ingress_controller_response_size_sum{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m]))", - "format": "time_series", - "hide": false, - "interval": "10s", - "intervalFactor": 1, - "legendFormat": "Sent", - "metric": "network", - "refId": "B", - "step": 10 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Network I/O pressure", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "transparent": false, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": false - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "max - istio-proxy": "#890f02", - "max - master": "#bf1b00", - "max - prometheus": "#bf1b00" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": 2, - "editable": false, - "error": false, - "fill": 0, - "grid": {}, - "gridPos": { - "h": 6, - "w": 8, - "x": 8, - "y": 10 - }, - "id": 77, - "isNew": true, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": 200, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "avg(nginx_ingress_controller_nginx_process_resident_memory_bytes{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}) ", - "format": "time_series", - "instant": false, - "interval": "10s", - "intervalFactor": 1, - "legendFormat": "nginx", - "metric": "container_memory_usage:sort_desc", - "refId": "A", - "step": 10 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Average Memory Usage", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "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": false - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "max - istio-proxy": "#890f02", - "max - master": "#bf1b00" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": 3, - "editable": false, - "error": false, - "fill": 0, - "grid": {}, - "gridPos": { - "h": 6, - "w": 8, - "x": 16, - "y": 10 - }, - "height": "", - "id": 79, - "isNew": true, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sort": null, - "sortDesc": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "avg (rate (nginx_ingress_controller_nginx_process_cpu_seconds_total{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m])) ", - "format": "time_series", - "interval": "10s", - "intervalFactor": 1, - "legendFormat": "nginx", - "metric": "container_cpu", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - { - "colorMode": "critical", - "fill": true, - "line": true, - "op": "gt" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Average CPU Usage", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "transparent": false, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "none", - "label": "cores", - "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": 24, - "x": 0, - "y": 16 - }, - "hideTimeOverride": false, - "id": 75, - "links": [], - "pageSize": 7, - "repeat": null, - "repeatDirection": "h", - "scroll": true, - "showHeader": true, - "sort": { - "col": 1, - "desc": true - }, - "styles": [ - { - "alias": "Ingress", - "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, - "pattern": "ingress", - "preserveFormat": false, - "sanitize": false, - "thresholds": [], - "type": "string", - "unit": "short" - }, - { - "alias": "Requests", - "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, - "pattern": "Value #A", - "thresholds": [ - "" - ], - "type": "number", - "unit": "ops" - }, - { - "alias": "Errors", - "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, - "pattern": "Value #B", - "thresholds": [], - "type": "number", - "unit": "ops" - }, - { - "alias": "P50 Latency", - "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": 0, - "link": false, - "pattern": "Value #C", - "thresholds": [], - "type": "number", - "unit": "dtdurations" - }, - { - "alias": "P90 Latency", - "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": 0, - "pattern": "Value #D", - "thresholds": [], - "type": "number", - "unit": "dtdurations" - }, - { - "alias": "P99 Latency", - "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": 0, - "pattern": "Value #E", - "thresholds": [], - "type": "number", - "unit": "dtdurations" - }, - { - "alias": "IN", - "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, - "pattern": "Value #F", - "thresholds": [ - "" - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "", - "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, - "pattern": "Time", - "thresholds": [], - "type": "hidden", - "unit": "short" - }, - { - "alias": "OUT", - "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": "Value #G", - "thresholds": [], - "type": "number", - "unit": "Bps" - } - ], - "targets": [ - { - "expr": "histogram_quantile(0.50, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", - "format": "table", - "hide": false, - "instant": true, - "intervalFactor": 1, - "legendFormat": "{{ ingress }}", - "refId": "C" - }, - { - "expr": "histogram_quantile(0.90, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", - "format": "table", - "hide": false, - "instant": true, - "intervalFactor": 1, - "legendFormat": "{{ ingress }}", - "refId": "D" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", - "format": "table", - "hide": false, - "instant": true, - "intervalFactor": 1, - "legendFormat": "{{ destination_service }}", - "refId": "E" - }, - { - "expr": "sum(irate(nginx_ingress_controller_request_size_sum{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", - "format": "table", - "hide": false, - "instant": true, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ ingress }}", - "refId": "F" - }, - { - "expr": "sum(irate(nginx_ingress_controller_response_size_sum{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", - "format": "table", - "instant": true, - "intervalFactor": 1, - "legendFormat": "{{ ingress }}", - "refId": "G" - } - ], - "timeFrom": null, - "title": "Ingress Percentile Response Times and Transfer Rates", - "transform": "table", - "transparent": false, - "type": "table" - }, - { - "columns": [ - { - "text": "Current", - "value": "current" - } - ], - "datasource": "$datasource", - "fontSize": "100%", - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 24 - }, - "height": "1024", - "id": 85, - "links": [], - "pageSize": 7, - "scroll": true, - "showHeader": true, - "sort": { - "col": 1, - "desc": false - }, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "date" - }, - { - "alias": "TTL", - "colorMode": "cell", - "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": 0, - "pattern": "Current", - "thresholds": [ - "0", - "691200" - ], - "type": "number", - "unit": "s" - }, - { - "alias": "", - "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": "avg(nginx_ingress_controller_ssl_expire_time_seconds{kubernetes_pod_name=~\"$controller\",namespace=~\"$namespace\",ingress=~\"$ingress\"}) by (host) - time()", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{ host }}", - "metric": "gke_letsencrypt_cert_expiration", - "refId": "A", - "step": 1 - } - ], - "title": "Ingress Certificate Expiry", - "transform": "timeseries_aggregations", - "type": "table" - } - ], - "refresh": "5s", - "schemaVersion": 16, - "style": "dark", - "tags": [ - "nginx" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": ".*", - "current": { - "text": "All", - "value": "$__all" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": "Namespace", - "multi": false, - "name": "namespace", - "options": [], - "query": "label_values(nginx_ingress_controller_config_hash, controller_namespace)", - "refresh": 1, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "text": "All", - "value": "$__all" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": "Controller Class", - "multi": false, - "name": "controller_class", - "options": [], - "query": "label_values(nginx_ingress_controller_config_hash{namespace=~\"$namespace\"}, controller_class) ", - "refresh": 1, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "text": "All", - "value": "$__all" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": "Controller", - "multi": false, - "name": "controller", - "options": [], - "query": "label_values(nginx_ingress_controller_config_hash{namespace=~\"$namespace\",controller_class=~\"$controller_class\"}, controller_pod) ", - "refresh": 1, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "tags": [], - "text": "All", - "value": "$__all" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": "Ingress", - "multi": false, - "name": "ingress", - "options": [], - "query": "label_values(nginx_ingress_controller_requests{namespace=~\"$namespace\",controller_class=~\"$controller_class\",controller_pod=~\"$controller\"}, ingress) ", - "refresh": 1, - "regex": "", - "sort": 2, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "2m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, - "timezone": "browser", - "title": "NGINX / Ingress Controller", - "uid": "nginx", - "version": 1 -} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/ingress-nginx/request-handling-performance.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/ingress-nginx/request-handling-performance.json deleted file mode 100644 index 156e33123d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/ingress-nginx/request-handling-performance.json +++ /dev/null @@ -1,963 +0,0 @@ -{ - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "description": "", - "editable": true, - "gnetId": 9614, - "graphTooltip": 1, - "id": null, - "iteration": 1582146566338, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "Total time taken for nginx and upstream servers to process a request and send a response", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 91, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "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": "histogram_quantile(\n 0.5,\n sum by (le)(\n rate(\n nginx_ingress_controller_request_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", - "interval": "", - "legendFormat": ".5", - "refId": "D" - }, - { - "expr": "histogram_quantile(\n 0.95,\n sum by (le)(\n rate(\n nginx_ingress_controller_request_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", - "interval": "", - "legendFormat": ".95", - "refId": "B" - }, - { - "expr": "histogram_quantile(\n 0.99,\n sum by (le)(\n rate(\n nginx_ingress_controller_request_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", - "interval": "", - "legendFormat": ".99", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Total request handling time", - "tooltip": { - "shared": true, - "sort": 0, - "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": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "The time spent on receiving the response from the upstream server", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 0 - }, - "hiddenSeries": false, - "id": 94, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "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": "histogram_quantile(\n 0.5,\n sum by (le)(\n rate(\n nginx_ingress_controller_response_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", - "instant": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": ".5", - "refId": "D" - }, - { - "expr": "histogram_quantile(\n 0.95,\n sum by (le)(\n rate(\n nginx_ingress_controller_response_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", - "interval": "", - "legendFormat": ".95", - "refId": "B" - }, - { - "expr": "histogram_quantile(\n 0.99,\n sum by (le)(\n rate(\n nginx_ingress_controller_response_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", - "interval": "", - "legendFormat": ".99", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Upstream response time", - "tooltip": { - "shared": true, - "sort": 0, - "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": 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": 0, - "y": 8 - }, - "hiddenSeries": false, - "id": 93, - "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": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": " sum by (path)(\n rate(\n nginx_ingress_controller_request_duration_seconds_count{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n", - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ path }}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Request volume by Path", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "reqps", - "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", - "description": "For each path observed, its median upstream response time", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 8 - }, - "hiddenSeries": false, - "id": 98, - "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": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(\n .5,\n sum by (le, path)(\n rate(\n nginx_ingress_controller_response_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ path }}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Median upstream response time by Path", - "tooltip": { - "shared": true, - "sort": 0, - "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": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "Percentage of 4xx and 5xx responses among all responses.", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 16 - }, - "hiddenSeries": false, - "id": 100, - "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 as zero", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (path) (rate(nginx_ingress_controller_request_duration_seconds_count{\n ingress =~ \"$ingress\",\n status =~ \"[4-5].*\"\n}[1m])) / sum by (path) (rate(nginx_ingress_controller_request_duration_seconds_count{\n ingress =~ \"$ingress\",\n}[1m]))", - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ path }}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Response error rate by Path", - "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": 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", - "description": "For each path observed, the sum of upstream request time", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 16 - }, - "hiddenSeries": false, - "id": 102, - "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": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (path) (rate(nginx_ingress_controller_response_duration_seconds_sum{ingress =~ \"$ingress\"}[1m]))", - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ path }}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Upstream time consumed by Path", - "tooltip": { - "shared": true, - "sort": 0, - "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": 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": 0, - "y": 24 - }, - "hiddenSeries": false, - "id": 101, - "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": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": " sum (\n rate(\n nginx_ingress_controller_request_duration_seconds_count{\n ingress =~ \"$ingress\",\n status =~\"[4-5].*\",\n }[1m]\n )\n ) by(path, status)\n", - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ path }} {{ status }}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Response error volume by Path", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "reqps", - "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": 24 - }, - "hiddenSeries": false, - "id": 99, - "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": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum (\n rate (\n nginx_ingress_controller_response_size_sum {\n ingress =~ \"$ingress\",\n }[1m]\n )\n) by (path) / sum (\n rate(\n nginx_ingress_controller_response_size_count {\n ingress =~ \"$ingress\",\n }[1m]\n )\n) by (path)\n", - "hide": false, - "instant": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ path }}", - "refId": "D" - }, - { - "expr": " sum (rate(nginx_ingress_controller_response_size_bucket{\n ingress =~ \"$ingress\",\n }[1m])) by (le)\n", - "hide": true, - "legendFormat": "{{le}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Average response size by Path", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "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": 8, - "w": 12, - "x": 0, - "y": 32 - }, - "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": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum (\n rate(\n nginx_ingress_controller_ingress_upstream_latency_seconds_sum {\n ingress =~ \"$ingress\",\n }[1m]\n)) / sum (\n rate(\n nginx_ingress_controller_ingress_upstream_latency_seconds_count {\n ingress =~ \"$ingress\",\n }[1m]\n )\n)\n", - "hide": false, - "instant": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "average", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Upstream service latency", - "tooltip": { - "shared": true, - "sort": 0, - "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": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": "30s", - "schemaVersion": 22, - "style": "dark", - "tags": [ - "nginx" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": ".*", - "current": {}, - "datasource": "$datasource", - "definition": "label_values(nginx_ingress_controller_requests, ingress) ", - "hide": 0, - "includeAll": true, - "label": "Service Ingress", - "multi": false, - "name": "ingress", - "options": [], - "query": "label_values(nginx_ingress_controller_requests, ingress) ", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 2, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "2m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, - "timezone": "browser", - "title": "NGINX / Request Handling Performance", - "uid": "4GFbkOsZk", - "version": 1 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/cluster/rancher-cluster-nodes.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/cluster/rancher-cluster-nodes.json deleted file mode 100644 index d1cc3b70ac..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/cluster/rancher-cluster-nodes.json +++ /dev/null @@ -1,793 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 28, - "links": [], - "panels": [ - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode=\"idle\"}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "{{instance}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Load[5m] ({{instance}})" - }, - "properties": [] - } - ] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_load1 OR avg_over_time(windows_system_processor_queue_length[1m])) by (instance)", - "interval": "", - "legendFormat": "Load[1m] ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(node_load5 OR avg_over_time(windows_system_processor_queue_length[5m])) by (instance)", - "interval": "", - "legendFormat": "Load[5m] ({{instance}})", - "refId": "B" - }, - { - "expr": "sum(node_load15 OR avg_over_time(windows_system_processor_queue_length[15m])) by (instance)", - "interval": "", - "legendFormat": "Load[15m] ({{instance}})", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Load Average", - "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": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - sum(node_memory_MemAvailable_bytes OR windows_os_physical_memory_free_bytes) by (instance) / sum(node_memory_MemTotal_bytes OR windows_cs_physical_memory_bytes) by (instance) ", - "interval": "", - "legendFormat": "{{instance}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"} OR windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) by (instance) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"} OR windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) by (instance))", - "interval": "", - "legendFormat": "{{instance}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_disk_read_bytes_total[$__rate_interval]) OR rate(windows_logical_disk_read_bytes_total[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Read ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(rate(node_disk_written_bytes_total[$__rate_interval]) OR rate(windows_logical_disk_write_bytes_total[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Write ({{instance}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 7 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_network_receive_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_received_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Receive Errors ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(rate(node_network_receive_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Receive Total ({{instance}})", - "refId": "B" - }, - { - "expr": "sum(rate(node_network_transmit_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_outbound_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Transmit Errors ({{instance}})", - "refId": "C" - }, - { - "expr": "sum(rate(node_network_receive_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_received_discarded_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Receive Dropped ({{instance}})", - "refId": "D" - }, - { - "expr": "sum(rate(node_network_transmit_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_outbound_discarded{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Transmit Dropped ({{instance}})", - "refId": "E" - }, - { - "expr": "sum(rate(node_network_transmit_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Transmit Total ({{instance}})", - "refId": "F" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "pps", - "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": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval]) OR rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Transmit Total ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval]) OR rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Receive Total ({{instance}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Cluster (Nodes)", - "uid": "rancher-cluster-nodes-1", - "version": 3 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/cluster/rancher-cluster.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/cluster/rancher-cluster.json deleted file mode 100644 index ec977f55d1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/cluster/rancher-cluster.json +++ /dev/null @@ -1,776 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 28, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode=\"idle\"}[$__rate_interval]))", - "legendFormat": "Total", - "interval": "", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Load[5m]" - }, - "properties": [] - } - ] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_load1 OR avg_over_time(windows_system_processor_queue_length[1m]))", - "interval": "", - "legendFormat": "Load[1m]", - "refId": "A" - }, - { - "expr": "sum(node_load5 OR avg_over_time(windows_system_processor_queue_length[5m]))", - "interval": "", - "legendFormat": "Load[5m]", - "refId": "B" - }, - { - "expr": "sum(node_load15 OR avg_over_time(windows_system_processor_queue_length[15m]))", - "interval": "", - "legendFormat": "Load[15m]", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Load Average", - "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": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - sum(node_memory_MemAvailable_bytes OR windows_os_physical_memory_free_bytes) / sum(node_memory_MemTotal_bytes OR windows_cs_physical_memory_bytes)", - "legendFormat": "Total", - "interval": "", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"} OR windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"} OR windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}))", - "legendFormat": "Total", - "interval": "", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_disk_read_bytes_total[$__rate_interval]) OR rate(windows_logical_disk_read_bytes_total[$__rate_interval]))", - "interval": "", - "legendFormat": "Read", - "refId": "A" - }, - { - "expr": "sum(rate(node_disk_written_bytes_total[$__rate_interval]) OR rate(windows_logical_disk_write_bytes_total[$__rate_interval]))", - "interval": "", - "legendFormat": "Write", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - }, - { - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 7 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(sum(rate(node_network_receive_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Receive Errors", - "refId": "A" - }, - { - "expr": "(sum(rate(node_network_receive_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Receive Total", - "refId": "B" - }, - { - "expr": "(sum(rate(node_network_transmit_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_outbound_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Transmit Errors", - "refId": "C" - }, - { - "expr": "(sum(rate(node_network_receive_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_discarded_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Receive Dropped", - "refId": "D" - }, - { - "expr": "(sum(rate(node_network_transmit_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_outbound_discarded{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Transmit Dropped", - "refId": "E" - }, - { - "expr": "(sum(rate(node_network_transmit_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Transmit Total", - "refId": "F" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "pps", - "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 - } - }, - { - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval]) OR rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval]))", - "interval": "", - "legendFormat": "Transmit Total", - "refId": "A" - }, - { - "expr": "sum(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval]) OR rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval]))", - "interval": "", - "legendFormat": "Receive Total", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Cluster", - "uid": "rancher-cluster-1", - "version": 3 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/bundle.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/bundle.json deleted file mode 100644 index 698f48aeed..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/bundle.json +++ /dev/null @@ -1,246 +0,0 @@ -{ - "description": "Bundle", - "graphTooltip": 1, - "panels": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 0 - }, - "id": 1, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Bundles", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 0 - }, - "id": 2, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_not_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_out_of_sync{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Out of Sync" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_err_applied{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Err Applied" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Modified" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_pending{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Pending" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_wait_applied{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Wait Applied" - } - ], - "title": "Bundles", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 3, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_not_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_out_of_sync{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Out of Sync" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_err_applied{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Err Applied" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Modified" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_pending{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Pending" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundle_wait_applied{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Wait Applied" - } - ], - "title": "Bundles", - "type": "timeseries" - } - ], - "schemaVersion": 39, - "templating": { - "list": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "name": "namespace", - "query": "label_values(fleet_bundle_desired_ready, exported_namespace)", - "refresh": 2, - "type": "query" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "includeAll": true, - "name": "name", - "query": "label_values(fleet_bundle_desired_ready{exported_namespace=~\"$namespace\"}, name)", - "refresh": 2, - "type": "query" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timezone": "utc", - "title": "Fleet / Bundle", - "uid": "fleet-bundle" -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/bundledeployment.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/bundledeployment.json deleted file mode 100644 index c81f7a6212..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/bundledeployment.json +++ /dev/null @@ -1,219 +0,0 @@ -{ - "description": "BundleDeployment", - "graphTooltip": 1, - "panels": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 0 - }, - "id": 1, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Ready\"}) / sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\"})" - } - ], - "title": "Ready BundleDeployments", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 0 - }, - "id": 2, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Ready\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"NotReady\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"WaitApplied\"})", - "legendFormat": "Wait Applied" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"ErrApplied\"})", - "legendFormat": "Err Applied" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"OutOfSync\"})", - "legendFormat": "OutOfSync" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Pending\"})", - "legendFormat": "Pending" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Modified\"})", - "legendFormat": "Modified" - } - ], - "title": "BundleDeployments", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 3, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Ready\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"NotReady\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"WaitApplied\"})", - "legendFormat": "Wait Applied" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"ErrApplied\"})", - "legendFormat": "Err Applied" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"OutOfSync\"})", - "legendFormat": "OutOfSync" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Pending\"})", - "legendFormat": "Pending" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Modified\"})", - "legendFormat": "Modified" - } - ], - "title": "BundleDeployments", - "type": "timeseries" - } - ], - "schemaVersion": 39, - "templating": { - "list": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "name": "namespace", - "query": "label_values(fleet_bundledeployment_state, cluster_namespace)", - "refresh": 2, - "type": "query" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timezone": "utc", - "title": "Fleet / BundleDeployment", - "uid": "fleet-bundledeployment" -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/cluster.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/cluster.json deleted file mode 100644 index 73bdea4834..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/cluster.json +++ /dev/null @@ -1,484 +0,0 @@ -{ - "description": "Cluster", - "graphTooltip": 1, - "panels": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 0 - }, - "id": 1, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_cluster_desired_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Git Repos", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 0 - }, - "id": 2, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_desired_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - } - ], - "title": "Git Repos", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 3, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_desired_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - } - ], - "title": "Git Repos", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 13 - }, - "id": 4, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_cluster_resources_count_desiredready{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Resources", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 13 - }, - "id": 5, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_desiredready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_notready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Missing" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Modified" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Unknown" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_orphaned{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Orphaned" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_waitapplied{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Wait Applied" - } - ], - "title": "Resources", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 21 - }, - "id": 6, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_desiredready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_notready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Missing" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Modified" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Unknown" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_orphaned{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Orphaned" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_resources_count_waitapplied{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Wait Applied" - } - ], - "title": "Resources", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 26 - }, - "id": 7, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"Ready\"}) / sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Clusters", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 26 - }, - "id": 8, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"Ready\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"NotReady\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"WaitCheckIn\"})", - "legendFormat": "Wait Check In" - } - ], - "title": "Clusters", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 34 - }, - "id": 9, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"Ready\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"NotReady\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"WaitCheckIn\"})", - "legendFormat": "Wait Check In" - } - ], - "title": "Clusters", - "type": "timeseries" - } - ], - "schemaVersion": 39, - "templating": { - "list": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "name": "namespace", - "query": "label_values(fleet_cluster_desired_ready_git_repos, exported_namespace)", - "refresh": 2, - "type": "query" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "includeAll": true, - "name": "name", - "query": "label_values(fleet_cluster_desired_ready_git_repos{exported_namespace=~\"$namespace\"}, name)", - "refresh": 2, - "type": "query" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timezone": "utc", - "title": "Fleet / Cluster", - "uid": "fleet-cluster" -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/clustergroup.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/clustergroup.json deleted file mode 100644 index ce3df87b21..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/clustergroup.json +++ /dev/null @@ -1,468 +0,0 @@ -{ - "description": "ClusterGroup", - "graphTooltip": 1, - "panels": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 0 - }, - "id": 1, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_cluster_group_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Bundles", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 0 - }, - "id": 2, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - } - ], - "title": "Bundles", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 3, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - } - ], - "title": "Bundles", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 13 - }, - "id": 4, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "(sum(fleet_cluster_group_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"}) - sum(fleet_cluster_group_non_ready_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})) / sum(fleet_cluster_group_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Clusters", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 13 - }, - "id": 5, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Total" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_non_ready_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Non Ready" - } - ], - "title": "Clusters", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 21 - }, - "id": 6, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Total" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_non_ready_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Non Ready" - } - ], - "title": "Clusters", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 26 - }, - "id": 7, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_cluster_group_resource_count_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Resources", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 26 - }, - "id": 8, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_notready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Missing" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Modified" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_orphaned{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Orphaned" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Unknown" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_waitapplied{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Wait Applied" - } - ], - "title": "Resources", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 34 - }, - "id": 9, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_notready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Missing" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Modified" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_orphaned{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Orphaned" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Unknown" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_cluster_group_resource_count_waitapplied{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Wait Applied" - } - ], - "title": "Resources", - "type": "timeseries" - } - ], - "schemaVersion": 39, - "templating": { - "list": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "name": "namespace", - "query": "label_values(fleet_cluster_group_bundle_desired_ready, exported_namespace)", - "refresh": 2, - "type": "query" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "includeAll": true, - "name": "name", - "query": "label_values(fleet_cluster_group_bundle_desired_ready{exported_namespace=~\"$namespace\"}, name)", - "refresh": 2, - "type": "query" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timezone": "utc", - "title": "Fleet / ClusterGroup", - "uid": "fleet-cluster-group" -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/controller-runtime.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/controller-runtime.json deleted file mode 100644 index 23a81f2a8c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/controller-runtime.json +++ /dev/null @@ -1,454 +0,0 @@ -{ - "description": "Controller Runtime", - "graphTooltip": 1, - "panels": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 1, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "controller_runtime_active_workers{job=\"$job\", namespace=\"$namespace\"}", - "legendFormat": "{{controller}} {{instance}}" - } - ], - "title": "Number of Workers in Use", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 2, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(rate(controller_runtime_reconcile_errors_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", - "legendFormat": "{{instance}} {{pod}}" - } - ], - "title": "Reconciliation Error Count per Controller", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 16 - }, - "id": 3, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(rate(controller_runtime_reconcile_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", - "legendFormat": "{{instance}} {{pod}}" - } - ], - "title": "Total Reconciliation Count per Controller", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 24 - }, - "id": 4, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "workqueue_depth{job=\"$job\", namespace=\"$namespace\"}", - "legendFormat": "{{instance}} {{pod}}" - } - ], - "title": "WorkQueue Depth", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 32 - }, - "id": 5, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "histogram_quantile(0.50, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "legendFormat": "P50 {{name}}" - } - ], - "title": "Seconds for Items Stay in Queue (before being requested) P50", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 40 - }, - "id": 6, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "histogram_quantile(0.90, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "legendFormat": "P90 {{name}}" - } - ], - "title": "Seconds for Items Stay in Queue (before being requested) P90", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 48 - }, - "id": 7, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "legendFormat": "P99 {{name}}" - } - ], - "title": "Seconds for Items Stay in Queue (before being requested) P99", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 56 - }, - "id": 8, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(rate(workqueue_adds_total{job=\"$job\", namespace=\"$namespace\"}[2m])) by (instance, name)", - "legendFormat": "{{name}} {{instance}}" - } - ], - "title": "Work Queue Add Rate", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 64 - }, - "id": 9, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "rate(workqueue_unfinished_work_seconds{job=\"$job\", namespace=\"$namespace\"}[5m])", - "legendFormat": "{{name}} {{instance}}" - } - ], - "title": "Unfinished Seconds", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 72 - }, - "id": 10, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "histogram_quantile(0.50, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "legendFormat": "P50 {{name}}" - } - ], - "title": "Seconds Processing Items from WorkQueue - 50th Percentile", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 80 - }, - "id": 11, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "histogram_quantile(0.90, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "legendFormat": "P90 {{name}}" - } - ], - "title": "Seconds Processing Items from WorkQueue - 90th Percentile", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 88 - }, - "id": 12, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "histogram_quantile(0.99, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "legendFormat": "P99 {{name}}" - } - ], - "title": "Seconds Processing Items from WorkQueue - 99th Percentile", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": null, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 96 - }, - "id": 13, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(rate(workqueue_retries_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name)", - "legendFormat": "{{name}} {{instance}}" - } - ], - "title": "Work Queue Retries Rate", - "type": "timeseries" - } - ], - "schemaVersion": 39, - "templating": { - "list": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "name": "namespace", - "query": "label_values(controller_runtime_reconcile_total, namespace)", - "refresh": 2, - "type": "query" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "name": "job", - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "refresh": 2, - "type": "query" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timezone": "utc", - "title": "Fleet / Controller-Runtime", - "uid": "fleet-controller-runtime" -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/gitrepo.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/gitrepo.json deleted file mode 100644 index 1a50c2937d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/fleet/gitrepo.json +++ /dev/null @@ -1,325 +0,0 @@ -{ - "description": "GitRepo", - "graphTooltip": 1, - "panels": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 0 - }, - "id": 1, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_gitrepo_desired_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Clusters", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 0 - }, - "id": 2, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_desired_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - } - ], - "title": "Clusters", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 3, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_desired_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - } - ], - "title": "Clusters", - "type": "timeseries" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": "percentunit" - } - }, - "gridPos": { - "h": 5, - "w": 7, - "x": 0, - "y": 13 - }, - "id": 4, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_gitrepo_resources_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})" - } - ], - "title": "Ready Resources", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 5, - "w": 17, - "x": 7, - "y": 13 - }, - "id": 5, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_not_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Missing" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Modified" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Unknown" - } - ], - "title": "Resources", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "unit": null - } - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 21 - }, - "id": 6, - "pluginVersion": "v11.0.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Desired Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_not_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Not Ready" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Missing" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Modified" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "expr": "sum(fleet_gitrepo_resources_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", - "legendFormat": "Unknown" - } - ], - "title": "Resources", - "type": "timeseries" - } - ], - "schemaVersion": 39, - "templating": { - "list": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "name": "namespace", - "query": "label_values(fleet_gitrepo_desired_ready_clusters, exported_namespace)", - "refresh": 2, - "type": "query" - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "includeAll": true, - "name": "name", - "query": "label_values(fleet_gitrepo_desired_ready_clusters{exported_namespace=~\"$namespace\"}, name)", - "refresh": 2, - "type": "query" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timezone": "utc", - "title": "Fleet / GitRepo", - "uid": "fleet-gitrepo" -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/home/rancher-default-home.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/home/rancher-default-home.json deleted file mode 100644 index 3fce207561..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/home/rancher-default-home.json +++ /dev/null @@ -1,1290 +0,0 @@ -{ - "annotations": { - "list": [] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 0, - "id": null, - "links": [], - "panels": [ - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 1, - "title": "", - "type": "welcome" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": true, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "decimals": 2, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "percent", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": true, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 4 - }, - "height": "180px", - "id": 6, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "(1 - (avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode=\"idle\"}[5m])))) * 100", - "format": "time_series", - "interval": "10s", - "intervalFactor": 1, - "refId": "A", - "step": 10 - } - ], - "thresholds": "65, 90", - "title": "CPU Utilization", - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": true, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "percent", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": true, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 4 - }, - "height": "180px", - "id": 4, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "(1 - sum({__name__=~\"node_memory_MemAvailable_bytes|windows_os_physical_memory_free_bytes\"}) / sum({__name__=~\"node_memory_MemTotal_bytes|windows_cs_physical_memory_bytes\"})) * 100", - "format": "time_series", - "interval": "10s", - "intervalFactor": 1, - "refId": "A", - "step": 10 - } - ], - "thresholds": "65, 90", - "title": "Memory Utilization", - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": true, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "decimals": 2, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "percent", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": true, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 5, - "w": 8, - "x": 16, - "y": 4 - }, - "height": "180px", - "id": 7, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "(1 - (((sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0))) / ((sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0))))) * 100", - "format": "time_series", - "interval": "10s", - "intervalFactor": 1, - "metric": "", - "refId": "A", - "step": 10 - } - ], - "thresholds": "65, 90", - "title": "Disk Utilization", - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "decimals": 2, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 0, - "y": 9 - }, - "height": "1px", - "id": 11, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": " cores", - "postfixFontSize": "30%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode!=\"idle\"}[5m]))", - "format": "time_series", - "interval": "10s", - "intervalFactor": 1, - "refId": "A", - "step": 10 - } - ], - "thresholds": "", - "title": "CPU Used", - "type": "singlestat", - "valueFontSize": "50%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "decimals": 2, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 4, - "y": 9 - }, - "height": "1px", - "id": 12, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": " cores", - "postfixFontSize": "30%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(kube_node_status_allocatable_cpu_cores{}) OR sum(kube_node_status_allocatable{resource=\"cpu\",unit=\"core\"})", - "interval": "10s", - "intervalFactor": 1, - "refId": "A", - "step": 10 - } - ], - "thresholds": "", - "title": "CPU Total", - "type": "singlestat", - "valueFontSize": "50%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "decimals": 2, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "bytes", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 8, - "y": 9 - }, - "height": "1px", - "id": 9, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "20%", - "prefix": "", - "prefixFontSize": "20%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum({__name__=~\"node_memory_MemTotal_bytes|windows_cs_physical_memory_bytes\"}) - sum({__name__=~\"node_memory_MemAvailable_bytes|windows_os_physical_memory_free_bytes\"})", - "interval": "10s", - "intervalFactor": 1, - "refId": "A", - "step": 10 - } - ], - "thresholds": "", - "title": "Memory Used", - "type": "singlestat", - "valueFontSize": "50%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "decimals": 2, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "bytes", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 12, - "y": 9 - }, - "height": "1px", - "id": 10, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(kube_node_status_allocatable_memory_bytes{}) OR sum(kube_node_status_allocatable{resource=\"memory\", unit=\"byte\"})", - "interval": "10s", - "intervalFactor": 1, - "refId": "A", - "step": 10 - } - ], - "thresholds": "", - "title": "Memory Total", - "type": "singlestat", - "valueFontSize": "50%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "decimals": 2, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "bytes", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 16, - "y": 9 - }, - "height": "1px", - "id": 13, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "(sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) - sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) - sum(windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0))", - "interval": "10s", - "intervalFactor": 1, - "refId": "A", - "step": 10 - } - ], - "thresholds": "", - "title": "Disk Used", - "type": "singlestat", - "valueFontSize": "50%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "Prometheus", - "decimals": 2, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "bytes", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 20, - "y": 9 - }, - "height": "1px", - "id": 14, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "(sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0))", - "interval": "10s", - "intervalFactor": 1, - "refId": "A", - "step": 10 - } - ], - "thresholds": "", - "title": "Disk Total", - "type": "singlestat", - "valueFontSize": "50%", - "valueMaps": [ - { - "op": "=", - "text": "0", - "value": "null" - } - ], - "valueName": "current" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "Prometheus", - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 8, - "x": 0, - "y": 12 - }, - "hiddenSeries": false, - "id": 2051, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - (avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode=\"idle\"}[$__rate_interval])))", - "format": "time_series", - "hide": false, - "instant": false, - "intervalFactor": 1, - "legendFormat": "Cluster", - "refId": "A" - }, - { - "expr": "1 - avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\", mode=\"idle\"}[$__rate_interval])) by (instance)", - "format": "time_series", - "hide": false, - "intervalFactor": 1, - "legendFormat": "{{ instance }}", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Usage", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "Prometheus", - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 8, - "x": 8, - "y": 12 - }, - "hiddenSeries": false, - "id": 2052, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "100 * (1 - sum({__name__=~\"node_memory_MemAvailable_bytes|windows_os_physical_memory_free_bytes\"}) / sum({__name__=~\"node_memory_MemTotal_bytes|windows_cs_physical_memory_bytes\"}))", - "format": "time_series", - "hide": false, - "instant": false, - "intervalFactor": 1, - "legendFormat": "Cluster", - "refId": "A" - }, - { - "expr": "100 * (1- sum({__name__=~\"node_memory_MemAvailable_bytes|windows_os_physical_memory_free_bytes\"}) by (instance) / sum({__name__=~\"node_memory_MemTotal_bytes|windows_cs_physical_memory_bytes\"}) by (instance))", - "format": "time_series", - "hide": false, - "intervalFactor": 1, - "legendFormat": "{{ instance }}", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Usage", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percent", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "Prometheus", - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 8, - "x": 16, - "y": 12 - }, - "hiddenSeries": false, - "id": 2053, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(1 - ((sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"} OR on() vector(0)))) / ((sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0)))) * 100", - "legendFormat": "Cluster", - "refId": "A" - }, - { - "expr": "(1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"}) by (instance)) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) by (instance)) * 100", - "hide": false, - "legendFormat": "{{ instance }}", - "refId": "B" - }, - { - "expr": "(1 - (sum(windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) by (instance)) / sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) by (instance)) * 100", - "hide": false, - "legendFormat": "{{ instance }}", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk Usage", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "percent", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "folderId": 0, - "gridPos": { - "h": 15, - "w": 12, - "x": 0, - "y": 18 - }, - "headings": true, - "id": 3, - "limit": 30, - "links": [], - "query": "", - "recent": true, - "search": true, - "starred": false, - "tags": [], - "title": "Dashboards", - "type": "dashlist" - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 18 - }, - "id": 2055, - "options": { - "content": "## About Rancher Monitoring\n\nRancher Monitoring is a Helm chart developed by Rancher that is powered by [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator). It is based on the upstream [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) Helm chart maintained by the Prometheus community.\n\nBy default, the chart deploys Grafana alongside a set of Grafana dashboards curated by the [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) project.\n\nFor more information on how Rancher Monitoring differs from [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack), please view the CHANGELOG.md of the rancher-monitoring chart located in the [rancher/charts](https://github.com/rancher/charts) repository.\n\nFor more information about how to configure Rancher Monitoring, please view the [Rancher docs](https://rancher.com/docs/rancher/v2.x/en/).\n\n", - "mode": "markdown" - }, - "pluginVersion": "7.1.0", - "timeFrom": null, - "timeShift": null, - "title": "", - "type": "text" - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "hidden": true, - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ], - "type": "timepicker" - }, - "timezone": "browser", - "title": "Home", - "uid": "rancher-home-1", - "version": 5 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-etcd-nodes.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-etcd-nodes.json deleted file mode 100644 index 8af4b81ce0..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-etcd-nodes.json +++ /dev/null @@ -1,687 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 32, - "links": [], - "panels": [ - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "Prometheus", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(etcd_network_client_grpc_received_bytes_total{job=\"kube-etcd\"}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Client Traffic In ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(rate(etcd_network_client_grpc_sent_bytes_total{job=\"kube-etcd\"}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Client Traffic Out ({{instance}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "GRPC Client Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Load[5m]({{instance}})" - }, - "properties": [] - } - ] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(etcd_mvcc_db_total_size_in_bytes) by (instance)", - "interval": "", - "legendFormat": "DB Size ({{instance}})", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "DB Size", - "tooltip": { - "shared": true, - "sort": 0, - "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": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(grpc_server_started_total{grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"}) by (instance) - sum(grpc_server_handled_total{grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"}) by (instance)", - "interval": "", - "legendFormat": "Watch Streams ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(grpc_server_started_total{grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"}) by (instance) - sum(grpc_server_handled_total{grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"}) by (instance)", - "interval": "", - "legendFormat": "Lease Watch Stream ({{instance}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Active Streams", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(etcd_server_proposals_committed_total[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Proposal Committed ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(rate(etcd_server_proposals_applied_total[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Proposal Applied ({{instance}})", - "refId": "B" - }, - { - "expr": "sum(rate(etcd_server_proposals_failed_total[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "Proposal Failed ({{instance}})", - "refId": "C" - }, - { - "expr": "sum(etcd_server_proposals_pending) by (instance)", - "interval": "", - "legendFormat": "Proposal Pending ({{instance}})", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Raft Proposals", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(grpc_server_started_total{grpc_type=\"unary\"}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "RPC Rate ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(rate(grpc_server_handled_total{grpc_type=\"unary\",grpc_code!=\"OK\"}[$__rate_interval])) by (instance)", - "interval": "", - "legendFormat": "RPC Failure Rate ({{instance}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "RPC Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 0, - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "decimals": null, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 7 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_wal_fsync_duration_seconds_bucket[$__rate_interval])) by (instance, le))", - "interval": "", - "legendFormat": "WAL fsync ({{instance}})", - "refId": "A" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_backend_commit_duration_seconds_bucket[$__rate_interval])) by (instance, le))", - "interval": "", - "legendFormat": "DB fsync ({{instance}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk Sync Duration", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 2, - "format": "s", - "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 - } - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / etcd (Nodes)", - "uid": "rancher-etcd-nodes-1", - "version": 5 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-etcd.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-etcd.json deleted file mode 100644 index 0c058cafb9..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-etcd.json +++ /dev/null @@ -1,669 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 33, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "Prometheus", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(etcd_network_client_grpc_received_bytes_total{job=\"kube-etcd\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Client Traffic In", - "refId": "A" - }, - { - "expr": "sum(rate(etcd_network_client_grpc_sent_bytes_total{job=\"kube-etcd\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Client Traffic Out", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "GRPC Client Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "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": [ - { - "properties": [] - } - ] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(etcd_mvcc_db_total_size_in_bytes)", - "interval": "", - "legendFormat": "DB Size", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "DB Size", - "tooltip": { - "shared": true, - "sort": 0, - "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": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(grpc_server_started_total{grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"}) - sum(grpc_server_handled_total{grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"})", - "interval": "", - "legendFormat": "Watch Streams", - "refId": "A" - }, - { - "expr": "sum(grpc_server_started_total{grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"}) - sum(grpc_server_handled_total{grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"})", - "interval": "", - "legendFormat": "Lease Watch Stream", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Active Streams", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(etcd_server_proposals_committed_total[$__rate_interval]))", - "interval": "", - "legendFormat": "Proposal Committed", - "refId": "A" - }, - { - "expr": "sum(rate(etcd_server_proposals_applied_total[$__rate_interval]))", - "interval": "", - "legendFormat": "Proposal Applied", - "refId": "B" - }, - { - "expr": "sum(rate(etcd_server_proposals_failed_total[$__rate_interval]))", - "interval": "", - "legendFormat": "Proposal Failed", - "refId": "C" - }, - { - "expr": "sum(etcd_server_proposals_pending)", - "interval": "", - "legendFormat": "Proposal Pending", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Raft Proposals", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(grpc_server_started_total{grpc_type=\"unary\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "RPC Rate", - "refId": "A" - }, - { - "expr": "sum(rate(grpc_server_handled_total{grpc_type=\"unary\",grpc_code!=\"OK\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "RPC Failure Rate", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "RPC Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 0, - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "decimals": null, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 7 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_wal_fsync_duration_seconds_bucket[$__rate_interval])) by (instance, le))", - "interval": "", - "legendFormat": "WAL fsync", - "refId": "A" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_backend_commit_duration_seconds_bucket[$__rate_interval])) by (instance, le))", - "interval": "", - "legendFormat": "DB fsync", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk Sync Duration", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 2, - "format": "s", - "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 - } - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / etcd", - "uid": "rancher-etcd-1", - "version": 4 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-k8s-components-nodes.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-k8s-components-nodes.json deleted file mode 100644 index b31358eaaf..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-k8s-components-nodes.json +++ /dev/null @@ -1,527 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 30, - "links": [], - "panels": [ - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(apiserver_request_total[$__rate_interval])) by (instance, code)", - "interval": "", - "legendFormat": "{{code}}({{instance}})", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "API Server Request Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 0, - "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": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Load[5m]({{instance}})" - }, - "properties": [] - } - ] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"deployment\"}) by (instance, name)", - "interval": "", - "legendFormat": "Deployment Depth ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"volumes\"}) by (instance, name)", - "interval": "", - "legendFormat": "Volumes Depth ({{instance}})", - "refId": "B" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"replicaset\"}) by (instance, name)", - "interval": "", - "legendFormat": "ReplicaSet Depth ({{instance}})", - "refId": "C" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"service\"}) by (instance, name)", - "interval": "", - "legendFormat": "Service Depth ({{instance}})", - "refId": "D" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"serviceaccount\"}) by (instance, name)", - "interval": "", - "legendFormat": "ServiceAccount Depth ({{instance}})", - "refId": "E" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"endpoint\"}) by (instance, name)", - "interval": "", - "legendFormat": "Endpoint Depth ({{instance}})", - "refId": "F" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"daemonset\"}) by (instance, name)", - "interval": "", - "legendFormat": "DaemonSet Depth ({{instance}})", - "refId": "G" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"statefulset\"}) by (instance, name)", - "interval": "", - "legendFormat": "StatefulSet Depth ({{instance}})", - "refId": "H" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"replicationmanager\"}) by (instance, name)", - "interval": "", - "legendFormat": "ReplicationManager Depth ({{instance}})", - "refId": "I" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Controller Manager Queue Depth", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(kube_pod_status_scheduled{condition=\"false\"})", - "interval": "", - "legendFormat": "Failed To Schedule", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Pod Scheduling Status", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "{{instance}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"reading\"}) by (instance)", - "interval": "", - "legendFormat": "Reading ({{instance}})", - "refId": "A" - }, - { - "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"waiting\"}) by (instance)", - "interval": "", - "legendFormat": "Waiting ({{instance}})", - "refId": "B" - }, - { - "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"writing\"}) by (instance)", - "interval": "", - "legendFormat": "Writing ({{instance}})", - "refId": "C" - }, - { - "expr": "sum(ceil(increase(nginx_ingress_controller_nginx_process_connections_total{state=\"accepted\"}[$__rate_interval]))) by (instance)", - "interval": "", - "legendFormat": "Accepted ({{instance}})", - "refId": "D" - }, - { - "expr": "sum(ceil(increase(nginx_ingress_controller_nginx_process_connections_total{state=\"handled\"}[$__rate_interval]))) by (instance)", - "interval": "", - "legendFormat": "Handled ({{instance}})", - "refId": "E" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Ingress Controller Connections", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Kubernetes Components (Nodes)", - "uid": "rancher-k8s-components-nodes-1", - "version": 5 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-k8s-components.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-k8s-components.json deleted file mode 100644 index 44cf97f9fd..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/k8s/rancher-k8s-components.json +++ /dev/null @@ -1,519 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 31, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(apiserver_request_total[$__rate_interval])) by (code)", - "interval": "", - "legendFormat": "{{code}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "API Server Request Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 0, - "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": [ - { - "matcher": { - "id": "byName", - "options": "Load[5m]({{instance}})" - }, - "properties": [] - } - ] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"deployment\"}) by (name)", - "interval": "", - "legendFormat": "Deployment Depth", - "refId": "A" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"volumes\"}) by (name)", - "interval": "", - "legendFormat": "Volumes Depth", - "refId": "B" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"replicaset\"}) by (name)", - "interval": "", - "legendFormat": "Replicaset Depth", - "refId": "C" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"service\"}) by (name)", - "interval": "", - "legendFormat": "Service Depth", - "refId": "D" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"serviceaccount\"}) by (name)", - "interval": "", - "legendFormat": "ServiceAccount Depth", - "refId": "E" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"endpoint\"}) by (name)", - "interval": "", - "legendFormat": "Endpoint Depth", - "refId": "F" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"daemonset\"}) by (name)", - "interval": "", - "legendFormat": "DaemonSet Depth", - "refId": "G" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"statefulset\"}) by (name)", - "interval": "", - "legendFormat": "StatefulSet Depth", - "refId": "H" - }, - { - "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"replicationmanager\"}) by (name)", - "interval": "", - "legendFormat": "ReplicationManager Depth", - "refId": "I" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Controller Manager Queue Depth", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "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": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(kube_pod_status_scheduled{condition=\"false\"})", - "interval": "", - "legendFormat": "Failed To Schedule", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Pod Scheduling Status", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "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": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"reading\"})", - "interval": "", - "legendFormat": "Reading", - "refId": "A" - }, - { - "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"waiting\"})", - "interval": "", - "legendFormat": "Waiting", - "refId": "B" - }, - { - "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"writing\"})", - "interval": "", - "legendFormat": "Writing", - "refId": "C" - }, - { - "expr": "sum(ceil(increase(nginx_ingress_controller_nginx_process_connections_total{state=\"accepted\"}[$__rate_interval])))", - "interval": "", - "legendFormat": "Accepted", - "refId": "D" - }, - { - "expr": "sum(ceil(increase(nginx_ingress_controller_nginx_process_connections_total{state=\"handled\"}[$__rate_interval])))", - "interval": "", - "legendFormat": "Handled", - "refId": "E" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Ingress Controller Connections", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Kubernetes Components", - "uid": "rancher-k8s-components-1", - "version": 5 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/logging/fluentbit.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/logging/fluentbit.json deleted file mode 100644 index b00582c8a8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/logging/fluentbit.json +++ /dev/null @@ -1,760 +0,0 @@ -{ - "annotations": { - "list": [ - { - "$$hashKey": "object:7", - "builtIn": 1, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "description": "Monitoring of the logging-stack", - "editable": true, - "fiscalYearStartMonth": 0, - "gnetId": 13042, - "graphTooltip": 1, - "links": [], - "liveNow": false, - "panels": [ - { - "collapsed": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 19, - "panels": [], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "General", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 1 - }, - "hiddenSeries": false, - "id": 14, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "$$hashKey": "object:1802", - "alias": "/Error.*/", - "color": "#E02F44" - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "\nsum(rate(fluentbit_output_retries_total[1m]))", - "format": "time_series", - "hide": false, - "intervalFactor": 1, - "legendFormat": "Retry rate", - "range": true, - "refId": "A" - }, - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(fluentbit_output_errors_total[1m]))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "Error rate", - "range": true, - "refId": "C" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Fluentbit output error/retry rate", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1697", - "format": "ops", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:1698", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "Input and output total rates", - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 1 - }, - "hiddenSeries": false, - "id": 44, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(fluentbit_input_records_total[1m]))", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "input", - "range": true, - "refId": "A" - }, - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(fluentbit_output_proc_records_total[1m]))", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "output", - "range": true, - "refId": "B" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Fluentbit input/output rate", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 30, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(fluentbit_output_retries_total[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "range": true, - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current retry count", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 7 - }, - "hiddenSeries": false, - "id": 45, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(fluentbit_output_errors_total[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "range": true, - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current error count", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 13 - }, - "hiddenSeries": false, - "id": 46, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(fluentbit_input_records_total[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "range": true, - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Input records total", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 13 - }, - "hiddenSeries": false, - "id": 47, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(fluentbit_filter_drop_records_total[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "range": true, - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Dropped records total", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "refresh": false, - "schemaVersion": 39, - "tags": [ - "logging", - "fluentbit" - ], - "templating": { - "list": [ - { - "hide": 2, - "name": "DS_PROMETHEUS", - "query": "prometheus", - "skipUrlSync": false, - "type": "constant" - } - ] - }, - "time": { - "from": "2024-08-20T15:06:03.311Z", - "to": "2024-08-20T21:06:03.311Z" - }, - "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": "Rancher / Fluentbit", - "uid": "rancher-logging-fluentbit", - "version": 1, - "weekStart": "" -} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/logging/fluentd.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/logging/fluentd.json deleted file mode 100644 index 8861425ce1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/logging/fluentd.json +++ /dev/null @@ -1,3221 +0,0 @@ -{ - "annotations": { - "list": [ - { - "$$hashKey": "object:7", - "builtIn": 1, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "description": "Monitoring of the logging-stack", - "editable": true, - "fiscalYearStartMonth": 0, - "gnetId": 13042, - "graphTooltip": 1, - "links": [], - "liveNow": false, - "panels": [ - { - "collapsed": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 19, - "panels": [], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "General", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "If you see errors then you probbaly have serious issues with log processing, see https://docs.fluentd.org/buffer#handling-unrecoverable-errors\n\nRetries are normal but should occur only from time to time, otherwise check for network errors or destination is too slow and requires additional tuning per given provider.", - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 1 - }, - "hiddenSeries": false, - "id": 14, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "$$hashKey": "object:1802", - "alias": "/Error.*/", - "color": "#E02F44" - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_retry_count[1m]))", - "format": "time_series", - "hide": false, - "intervalFactor": 1, - "legendFormat": "Retry rate", - "refId": "A" - }, - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_num_errors[1m]))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "Error rate", - "refId": "C" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Fluentd output error/retry rate", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1697", - "format": "ops", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:1698", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "Input and output total rates", - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 1 - }, - "hiddenSeries": false, - "id": 44, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_input_status_num_records_total[1m]))", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "input", - "refId": "A" - }, - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_write_count[1m]))", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "output", - "refId": "B" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Fluentd input/output rate", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "This should not reach 0 otherwise logs are blocked from processing or even dropped", - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 16, - "y": 1 - }, - "hiddenSeries": false, - "id": 20, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "min(fluentd_output_status_buffer_available_space_ratio)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "lowest across all hosts", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Fluentd output status buffer available space ratio", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:918", - "decimals": 0, - "format": "percent", - "logBase": 1, - "max": "100", - "min": "0", - "show": true - }, - { - "$$hashKey": "object:919", - "decimals": 0, - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "total flush time", - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 6 - }, - "hiddenSeries": false, - "id": 21, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "$$hashKey": "object:906", - "alias": "count", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_flush_time_count[1m]))", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "time", - "refId": "A" - }, - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_slow_flush_count[1m]))", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "count", - "refId": "B" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Fluentd output status flush time count rate", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:400", - "decimals": 0, - "format": "ms", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:401", - "decimals": 0, - "format": "short", - "logBase": 1, - "min": "0", - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "Current total size of stage and queue buffers.\nfluentd_output_status_buffer_total_bytes", - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 6 - }, - "hiddenSeries": false, - "id": 13, - "legend": { - "alignAsTable": false, - "avg": true, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_buffer_total_bytes) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current total size of stage and queue buffers", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:321", - "format": "bytes", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:322", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "links": [], - "unitScale": true - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 16, - "y": 6 - }, - "hiddenSeries": false, - "id": 15, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.3.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_buffer_queue_length)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "total", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Fluentd output buffer queue", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1460", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:1461", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "collapsed": true, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 11 - }, - "id": 17, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_input_status_num_records_total", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 12 - }, - "hiddenSeries": false, - "id": 39, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) ", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "total", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Input entries rate (total)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_input_status_num_records_total", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 12 - }, - "hiddenSeries": false, - "id": 47, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) by (hostname)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{hostname}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Input entries rate per hostname", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_input_status_num_records_total", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 18 - }, - "hiddenSeries": false, - "id": 60, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) by (namespace)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{namespace}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Input entries rate per namespace", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_input_status_num_records_total", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 18 - }, - "hiddenSeries": false, - "id": 48, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) by (instance)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{namespace}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Input entries rate per instance", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "Input details", - "type": "row" - }, - { - "collapsed": true, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 12 - }, - "id": 59, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_input_status_num_records_total", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 25 - }, - "hiddenSeries": false, - "id": 49, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) by (tag)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{tag}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Input entries rate per tag", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "Input details (warning, very slow!)", - "type": "row" - }, - { - "collapsed": true, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 13 - }, - "id": 41, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_buffer_stage_length", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 32 - }, - "hiddenSeries": false, - "id": 22, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_buffer_stage_length) by (pod, type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current length of stage buffers", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_buffer_stage_byte_size", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 32 - }, - "hiddenSeries": false, - "id": 23, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_buffer_stage_byte_size) by (pod, type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current total size of stage buffers", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "bytes", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "Buffer stage", - "type": "row" - }, - { - "collapsed": true, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 14 - }, - "id": 43, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 39 - }, - "hiddenSeries": false, - "id": 50, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "max_over_time(fluentd_output_status_buffer_queue_length[1m])", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Maximum buffer length in last 1min", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 39 - }, - "hiddenSeries": false, - "id": 25, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "max_over_time(fluentd_output_status_buffer_total_bytes[1m])", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Maximum buffer bytes in last 1min", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "bytes", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_buffer_queue_length", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 45 - }, - "hiddenSeries": false, - "id": 24, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_buffer_queue_length) by (pod, type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current length of queue buffers", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_queue_byte_size", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 45 - }, - "hiddenSeries": false, - "id": 51, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_queue_byte_size) by (pod, type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current total size of queue buffers", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "bytes", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "Buffer queue", - "type": "row" - }, - { - "collapsed": true, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 15 - }, - "id": 46, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_buffer_available_space_ratio", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 52 - }, - "hiddenSeries": false, - "id": 26, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_buffer_available_space_ratio) by (pod, type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Ratio of available space in buffer", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "percent", - "logBase": 1, - "max": "100", - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "Buffer space", - "type": "row" - }, - { - "collapsed": true, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 16 - }, - "id": 53, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_retry_count", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 59 - }, - "hiddenSeries": false, - "id": 30, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_retry_count[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current retry counts", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_emit_records", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 59 - }, - "hiddenSeries": false, - "id": 33, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_emit_records[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current emit records", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_emit_count", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 65 - }, - "hiddenSeries": false, - "id": 32, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_emit_count[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current emit counts rate", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_rollback_count", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 65 - }, - "hiddenSeries": false, - "id": 35, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_rollback_count[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current rollback counts", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_write_count", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 71 - }, - "hiddenSeries": false, - "id": 34, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_write_count[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current write counts", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_slow_flush_count", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 71 - }, - "hiddenSeries": false, - "id": 37, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_slow_flush_count[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current slow flush counts", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_retry_wait", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 77 - }, - "hiddenSeries": false, - "id": 38, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_retry_wait[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current retry wait", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_flush_time_count", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 77 - }, - "hiddenSeries": false, - "id": 36, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_flush_time_count[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Total flush time", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "ms", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "Buffer retries", - "type": "row" - }, - { - "collapsed": true, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 17 - }, - "id": 57, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_num_errors", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 84 - }, - "hiddenSeries": false, - "id": 31, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(rate(fluentd_output_status_num_errors[1m])) by (type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Current number of errors rate", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "Buffer errors", - "type": "row" - }, - { - "collapsed": true, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 18 - }, - "id": 55, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 91 - }, - "hiddenSeries": false, - "id": 29, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "fluentd_output_status_buffer_newest_timekey - fluentd_output_status_buffer_oldest_timekey", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Timekey diff", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_buffer_newest_timekey", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 91 - }, - "hiddenSeries": false, - "id": 27, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_buffer_newest_timekey) by (pod, type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Newest timekey in buffer", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "description": "fluentd_output_status_buffer_oldest_timekey", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 97 - }, - "hiddenSeries": false, - "id": 28, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": false, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "sum(fluentd_output_status_buffer_oldest_timekey) by (pod, type)", - "format": "time_series", - "hide": false, - "interval": "", - "intervalFactor": 1, - "legendFormat": "{{pod}} {{ type }}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Oldest timekey in buffer", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:250", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], - "title": "Buffer timekeys", - "type": "row" - } - ], - "refresh": "10s", - "schemaVersion": 39, - "tags": [ - "fluentd", - "logging" - ], - "templating": { - "list": [ - { - "hide": 2, - "name": "DS_PROMETHEUS", - "query": "prometheus", - "skipUrlSync": false, - "type": "constant" - } - ] - }, - "time": { - "from": "now-3h", - "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": "Rancher / Fluentd", - "uid": "rancher-logging-fluentd", - "version": 1, - "weekStart": "" -} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/nodes/rancher-node-detail.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/nodes/rancher-node-detail.json deleted file mode 100644 index 920fb94cf7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/nodes/rancher-node-detail.json +++ /dev/null @@ -1,805 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 28, - "links": [], - "panels": [ - { - "aliasColors": { - "{{mode}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\", instance=\"$instance\"}[$__rate_interval])) by (mode)", - "interval": "", - "legendFormat": "{{mode}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Load[5m]" - }, - "properties": [] - } - ] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_load5{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[5m]))", - "interval": "", - "legendFormat": "Load[5m]", - "refId": "A" - }, - { - "expr": "sum(node_load1{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[1m]))", - "interval": "", - "legendFormat": "Load[1m]", - "refId": "B" - }, - { - "expr": "sum(node_load15{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[15m]))", - "interval": "", - "legendFormat": "Load[15m]", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Load Average", - "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": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - (node_memory_MemAvailable_bytes{instance=~\"$instance\"} OR windows_os_physical_memory_free_bytes{instance=~\"$instance\"}) / (node_memory_MemTotal_bytes{instance=~\"$instance\"} OR windows_cs_physical_memory_bytes{instance=~\"$instance\"})", - "interval": "", - "legendFormat": "Total", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": { - "{{device}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\", instance=~\"$instance\"} OR windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\", instance=~\"$instance\"}) by (device) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\", instance=~\"$instance\"} OR windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\", instance=~\"$instance\"}) by (device))", - "interval": "", - "legendFormat": "{{device}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": { - "{{device}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_disk_read_bytes_total{instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_logical_disk_read_bytes_total{instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Read ({{device}})", - "refId": "A" - }, - { - "expr": "sum(rate(node_disk_written_bytes_total{instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_logical_disk_write_bytes_total{instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Write ({{device}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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": { - "{{device}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 7 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_network_receive_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_received_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Receive Errors ({{device}})", - "refId": "A" - }, - { - "expr": "sum(rate(node_network_receive_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Receive Total ({{device}})", - "refId": "B" - }, - { - "expr": "sum(rate(node_network_transmit_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_outbound_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Transmit Errors ({{device}})", - "refId": "C" - }, - { - "expr": "sum(rate(node_network_receive_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_received_discarded_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Receive Dropped ({{device}})", - "refId": "D" - }, - { - "expr": "sum(rate(node_network_transmit_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_outbound_discarded{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Transmit Dropped ({{device}})", - "refId": "E" - }, - { - "expr": "sum(rate(node_network_transmit_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Transmit Total ({{device}})", - "refId": "F" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "pps", - "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": { - "{{device}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Transmit Total ({{device}})", - "refId": "A" - }, - { - "expr": "sum(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", - "interval": "", - "legendFormat": "Receive Total ({{device}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "instance", - "query": "label_values({__name__=~\"node_exporter_build_info|windows_exporter_build_info\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Node (Detail)", - "uid": "rancher-node-detail-1", - "version": 3 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/nodes/rancher-node.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/nodes/rancher-node.json deleted file mode 100644 index 367df3cc9d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/nodes/rancher-node.json +++ /dev/null @@ -1,792 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 28, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\", instance=\"$instance\", mode=\"idle\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Total", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Load[5m]" - }, - "properties": [] - } - ] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_load5{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[5m]))", - "interval": "", - "legendFormat": "Load[5m]", - "refId": "A" - }, - { - "expr": "sum(node_load1{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[1m]))", - "interval": "", - "legendFormat": "Load[1m]", - "refId": "B" - }, - { - "expr": "sum(node_load15{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[15m]))", - "interval": "", - "legendFormat": "Load[15m]", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Load Average", - "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": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - sum(node_memory_MemAvailable_bytes{instance=~\"$instance\"} OR windows_os_physical_memory_free_bytes{instance=~\"$instance\"}) / sum(node_memory_MemTotal_bytes{instance=~\"$instance\"} OR windows_cs_physical_memory_bytes{instance=~\"$instance\"})", - "interval": "", - "legendFormat": "Total", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\", instance=~\"$instance\"} OR windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\", instance=~\"$instance\"}) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\", instance=~\"$instance\"} OR windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\", instance=~\"$instance\"}))", - "interval": "", - "legendFormat": "Total", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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 - } - }, - { - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_disk_read_bytes_total{instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_logical_disk_read_bytes_total{instance=~\"$instance\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Read", - "refId": "A" - }, - { - "expr": "sum(rate(node_disk_written_bytes_total{instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_logical_disk_write_bytes_total{instance=~\"$instance\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Write", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - }, - { - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 7 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(sum(rate(node_network_receive_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Receive Errors", - "refId": "A" - }, - { - "expr": "(sum(rate(node_network_receive_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Receive Total", - "refId": "B" - }, - { - "expr": "(sum(rate(node_network_transmit_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_outbound_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Transmit Errors", - "refId": "C" - }, - { - "expr": "(sum(rate(node_network_receive_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_discarded_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Receive Dropped", - "refId": "D" - }, - { - "expr": "(sum(rate(node_network_transmit_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_outbound_discarded{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Transmit Dropped", - "refId": "E" - }, - { - "expr": "(sum(rate(node_network_transmit_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", - "interval": "", - "legendFormat": "Transmit Total", - "refId": "F" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "pps", - "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 - } - }, - { - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Transmit Total", - "refId": "A" - }, - { - "expr": "sum(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Receive Total", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "instance", - "query": "label_values({__name__=~\"node_exporter_build_info|windows_exporter_build_info\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Node", - "uid": "rancher-node-1", - "version": 3 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/performance/performance-debugging.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/performance/performance-debugging.json deleted file mode 100644 index 454bc39390..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/performance/performance-debugging.json +++ /dev/null @@ -1,1652 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "links": [], - "liveNow": false, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 22, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": true, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (handler_name) (rate(lasso_controller_reconcile_time_seconds_sum[5m]))\n/\nsum by (handler_name) (rate(lasso_controller_reconcile_time_seconds_count[5m])))", - "interval": "", - "legendFormat": "{{handler_name}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Handler Average Execution Times Over Last 5 Minutes (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1390", - "format": "short", - "label": "Execution Time in Seconds", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:1391", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 8 - }, - "hiddenSeries": false, - "id": 28, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (resource, method, code) (rate(steve_api_request_time_sum{resource!=\"subscribe\"}[5m]))\n/\nsum by (resource, method, code) (rate(steve_api_request_time_count{resource!=\"subscribe\"}[5m])))", - "interval": "", - "legendFormat": "{{resource}} {{method}} {{code}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Rancher API Average Request Times Over Last 5 Minutes (Top 20) (Subscribes Omitted)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:178", - "format": "ms", - "label": "", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:179", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 16 - }, - "hiddenSeries": false, - "id": 30, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "rate(steve_api_request_time_sum{resource=\"subscribe\"}[5m])\n/\nrate(steve_api_request_time_count{resource=\"subscribe\"}[5m])", - "interval": "", - "legendFormat": "{{resource}} {{method}} {{code}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Subscribe Average Request Times Over Last 5 Minutes", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:368", - "format": "ms", - "label": "", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:369", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 24 - }, - "hiddenSeries": false, - "id": 14, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,workqueue_depth)", - "interval": "", - "legendFormat": "{{name}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Lasso Controller Work Queue Depth (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1553", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:1554", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 13, - "w": 16, - "x": 0, - "y": 32 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": false, - "hideZero": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (id, resource, method, code) (steve_api_total_requests))", - "instant": false, - "interval": "", - "legendFormat": "{{id}} {{resource}} {{method}} {{code}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Number of Rancher Requests (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:290", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:291", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 16, - "x": 0, - "y": 45 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (id, resource, method) (steve_api_total_requests{code!=\"200\",code!=\"201\"}))", - "interval": "", - "legendFormat": "{{id}} {{resource}} {{method}} {{code}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Number of Failed Rancher API Requests (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:428", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:429", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 54 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (resource, method, code) (rate(k8s_proxy_store_request_time_sum[5m]))\n/\nsum by (resource, method, code) (rate(k8s_proxy_store_request_time_count[5m])))", - "interval": "", - "legendFormat": "{{resource}} {{method}} {{code}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "K8s Proxy Store Average Request Times Over Last 5 Minutes (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:662", - "format": "ms", - "label": "", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:663", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 62 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": true, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (resource, method, code) (rate(k8s_proxy_client_request_time_sum[5m]))\n/\nsum by (resource, method, code) (rate(k8s_proxy_client_request_time_count[5m])))", - "interval": "", - "legendFormat": "{{resource}} {{method}} {{code}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "K8s Proxy Client Average Request Times Over Last 5 Minutes (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1710", - "format": "ms", - "label": "", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:1711", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 70 - }, - "hiddenSeries": false, - "id": 10, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,lasso_controller_total_cached_object)", - "interval": "", - "legendFormat": "{{kind}} {{version}} {{group}} {{pod}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Cached Objects by GroupVersionKind (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:744", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:745", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 78 - }, - "hiddenSeries": false, - "id": 12, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (handler_name) (\nlasso_controller_total_handler_execution\n))", - "interval": "", - "legendFormat": "{{handler_name}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Lasso Handler Executions (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:824", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:825", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 86 - }, - "hiddenSeries": false, - "id": 32, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20, sum by (handler_name,controller_name) (\nincrease(lasso_controller_total_handler_execution[2m])\n))", - "interval": "", - "legendFormat": "{{controller_name}}.{{handler_name}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Handler Executions Over Last 2 Minutes (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 94 - }, - "hiddenSeries": false, - "id": 20, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (handler_name) (\nlasso_controller_total_handler_execution{has_error=\"true\"}\n))", - "interval": "", - "legendFormat": "{{handler_name}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Total Handler Executions with Error (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1230", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:1231", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 102 - }, - "hiddenSeries": false, - "id": 34, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,sum by (handler_name,controller_name) (\nincrease(lasso_controller_total_handler_execution{has_error=\"true\"}[2m])\n))", - "interval": "", - "legendFormat": "{{controller_name}}.{{handler_name}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Handler Executions Over Last 2 Minutes (Top 20)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 110 - }, - "hiddenSeries": false, - "id": 16, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "topk(20,session_server_total_transmit_bytes)", - "interval": "", - "legendFormat": "{{clientkey}} {{pod}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Data Transmitted by Remote Dialer Sessions (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1953", - "format": "decbytes", - "label": "", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:1954", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "$datasource" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 118 - }, - "hiddenSeries": false, - "id": 18, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "exemplar": true, - "expr": "session_server_total_transmit_error_bytes", - "interval": "", - "legendFormat": "{{clientkey}} {{pod}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Errors for Remote Dialer Sessions (Top 20)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:2045", - "format": "ms", - "label": "Error Data", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:2046", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 126 - }, - "hiddenSeries": false, - "id": 26, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "editorMode": "code", - "exemplar": true, - "expr": "session_server_total_add_websocket_session - (session_server_total_remove_websocket_session or (0 * session_server_total_add_websocket_session))", - "interval": "", - "legendFormat": "{{clientkey}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Remote Dialer Active Connections (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:2199", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:2200", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 134 - }, - "hiddenSeries": false, - "id": 35, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(session_server_total_remove_connections[$__rate_interval])", - "interval": "", - "legendFormat": "{{clientkey}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Remote Dialer Removed Connections Rate (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:2199", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:2200", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "$datasource" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 16, - "x": 0, - "y": 142 - }, - "hiddenSeries": false, - "id": 24, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "$datasource" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(session_server_total_add_connections[$__rate_interval])", - "interval": "", - "legendFormat": "{{clientkey}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Remote Dialer Added Connections Rate (Top 20)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:2117", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:2118", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "schemaVersion": 37, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "selected": false, - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "includeAll": false, - "label": "Data Source", - "multi": false, - "name": "datasource", - "options": [], - "query": "prometheus", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "type": "datasource" - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Rancher Performance Debugging", - "uid": "tfrfU0a7k", - "version": 1, - "weekStart": "" -} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/pods/rancher-pod-containers.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/pods/rancher-pod-containers.json deleted file mode 100644 index cf78a2204c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/pods/rancher-pod-containers.json +++ /dev/null @@ -1,636 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 28, - "iteration": 1618265214337, - "links": [], - "panels": [ - { - "aliasColors": { - "{{container}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(container_cpu_cfs_throttled_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "CFS throttled ({{container}})", - "refId": "A" - }, - { - "expr": "sum(rate(container_cpu_system_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container) OR sum(rate(windows_container_cpu_usage_seconds_kernelmode{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "System ({{container}})", - "refId": "B" - }, - { - "expr": "sum(rate(container_cpu_usage_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container) OR sum(rate(windows_container_cpu_usage_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Total ({{container}})", - "refId": "C" - }, - { - "expr": "sum(rate(container_cpu_user_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container) OR sum(rate(windows_container_cpu_usage_seconds_usermode{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "User ({{container}})", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "cpu", - "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": { - "{{container}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(container_memory_working_set_bytes{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"} OR windows_container_memory_usage_commit_bytes{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"}) by (container)", - "interval": "", - "legendFormat": "({{container}})", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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": { - "{{container}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_receive_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Receive Total ({{container}})", - "refId": "A" - }, - { - "expr": "sum(irate(container_network_transmit_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_transmit_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Transmit Total ({{container}})", - "refId": "B" - }, - { - "expr": "sum(irate(container_network_receive_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_receive_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Receive Dropped ({{container}})", - "refId": "C" - }, - { - "expr": "sum(irate(container_network_receive_errors_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Receive Errors ({{container}})", - "refId": "D" - }, - { - "expr": "sum(irate(container_network_transmit_errors_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Transmit Errors ({{container}})", - "refId": "E" - }, - { - "expr": "sum(irate(container_network_transmit_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_transmit_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Transmit Dropped ({{container}})", - "refId": "F" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "pps", - "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": { - "{{container}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_receive_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Receive Total ({{container}})", - "refId": "A" - }, - { - "expr": "sum(irate(container_network_transmit_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_transmit_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Transmit Total ({{container}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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": { - "{{container}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(container_fs_writes_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Write ({{container}})", - "refId": "A" - }, - { - "expr": "sum(rate(container_fs_reads_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", - "interval": "", - "legendFormat": "Read ({{container}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - } - ], - "refresh": false, - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "query": "label_values(kube_pod_info{}, namespace)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "pod", - "query": "label_values(kube_pod_info{namespace=\"$namespace\"}, pod)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Pod (Containers)", - "uid": "rancher-pod-containers-1", - "version": 8 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/pods/rancher-pod.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/pods/rancher-pod.json deleted file mode 100644 index 4859eccc74..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/pods/rancher-pod.json +++ /dev/null @@ -1,636 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 28, - "iteration": 1618265214337, - "links": [], - "panels": [ - { - "aliasColors": { - "": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(container_cpu_cfs_throttled_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "CFS throttled", - "refId": "A" - }, - { - "expr": "sum(rate(container_cpu_system_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) OR sum(rate(windows_container_cpu_usage_seconds_kernelmode{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "System", - "refId": "B" - }, - { - "expr": "sum(rate(container_cpu_usage_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) OR sum(rate(windows_container_cpu_usage_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Total", - "refId": "C" - }, - { - "expr": "sum(rate(container_cpu_user_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) OR sum(rate(windows_container_cpu_usage_seconds_usermode{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "User", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "cpu", - "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": { - "": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(container_memory_working_set_bytes{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"} OR windows_container_memory_usage_commit_bytes{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"})", - "interval": "", - "legendFormat": "Total", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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": { - "": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_receive_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Receive Total", - "refId": "A" - }, - { - "expr": "sum(irate(container_network_transmit_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_transmit_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Transmit Total", - "refId": "B" - }, - { - "expr": "sum(irate(container_network_receive_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_receive_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Receive Dropped", - "refId": "C" - }, - { - "expr": "sum(irate(container_network_receive_errors_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Receive Errors", - "refId": "D" - }, - { - "expr": "sum(irate(container_network_transmit_errors_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Transmit Errors", - "refId": "E" - }, - { - "expr": "sum(irate(container_network_transmit_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_transmit_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Transmit Dropped", - "refId": "F" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "pps", - "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": { - "": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_receive_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Receive Total", - "refId": "A" - }, - { - "expr": "sum(irate(container_network_transmit_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_transmit_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Transmit Total", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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": { - "": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(container_fs_writes_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Write", - "refId": "A" - }, - { - "expr": "sum(rate(container_fs_reads_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Read", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - } - ], - "refresh": false, - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "query": "label_values(kube_pod_info{}, namespace)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "pod", - "query": "label_values(kube_pod_info{namespace=\"$namespace\"}, pod)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Pod", - "uid": "rancher-pod-1", - "version": 8 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/workloads/rancher-workload-pods.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/workloads/rancher-workload-pods.json deleted file mode 100644 index 92c0d24a6e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/workloads/rancher-workload-pods.json +++ /dev/null @@ -1,652 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 28, - "iteration": 1618265214337, - "links": [], - "panels": [ - { - "aliasColors": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(sum(rate(container_cpu_cfs_throttled_seconds_total{namespace=~\"$namespace\",container=\"\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "CFS throttled ({{pod}})", - "refId": "A" - }, - { - "expr": "(sum(rate(container_cpu_system_seconds_total{namespace=~\"$namespace\",container=\"\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_kernelmode{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "System ({{pod}})", - "refId": "B" - }, - { - "expr": "(sum(rate(container_cpu_usage_seconds_total{namespace=~\"$namespace\",container=\"\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Total ({{pod}})", - "refId": "C" - }, - { - "expr": "(sum(rate(container_cpu_user_seconds_total{namespace=~\"$namespace\",container=\"\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_usermode{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "User ({{pod}})", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "cpu", - "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": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(sum(container_memory_working_set_bytes{namespace=~\"$namespace\",container=\"\"} OR windows_container_memory_usage_commit_bytes{namespace=~\"$namespace\"}) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "({{pod}})", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(sum(irate(container_network_receive_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Receive Total ({{pod}})", - "refId": "A" - }, - { - "expr": "(sum(irate(container_network_transmit_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Transmit Total ({{pod}})", - "refId": "B" - }, - { - "expr": "(sum(irate(container_network_receive_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Receive Dropped ({{pod}})", - "refId": "C" - }, - { - "expr": "(sum(irate(container_network_receive_errors_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Receive Errors ({{pod}})", - "refId": "D" - }, - { - "expr": "(sum(irate(container_network_transmit_errors_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Transmit Errors ({{pod}})", - "refId": "E" - }, - { - "expr": "(sum(irate(container_network_transmit_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Transmit Dropped ({{pod}})", - "refId": "F" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "pps", - "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": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(sum(irate(container_network_receive_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Receive Total ({{pod}})", - "refId": "A" - }, - { - "expr": "(sum(irate(container_network_transmit_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Transmit Total ({{pod}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(sum(rate(container_fs_writes_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Write ({{pod}})", - "refId": "A" - }, - { - "expr": "(sum(rate(container_fs_reads_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", - "interval": "", - "legendFormat": "Read ({{pod}})", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - } - ], - "refresh": false, - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "query": "query_result(kube_pod_info{namespace!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", - "refresh": 2, - "regex": "/.*namespace=\"([^\"]*)\"/", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "kind", - "query": "query_result(kube_pod_info{namespace=\"$namespace\", created_by_kind!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", - "refresh": 2, - "regex": "/.*created_by_kind=\"([^\"]*)\"/", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "workload", - "query": "query_result(kube_pod_info{namespace=\"$namespace\", created_by_kind=\"$kind\", created_by_name!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", - "refresh": 2, - "regex": "/.*created_by_name=\"([^\"]*)\"/", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Workload (Pods)", - "uid": "rancher-workload-pods-1", - "version": 8 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/workloads/rancher-workload.json b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/workloads/rancher-workload.json deleted file mode 100644 index 9f5317c2f0..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/rancher/workloads/rancher-workload.json +++ /dev/null @@ -1,652 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 28, - "iteration": 1618265214337, - "links": [], - "panels": [ - { - "aliasColors": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum((sum(rate(container_cpu_cfs_throttled_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "CFS throttled", - "refId": "A" - }, - { - "expr": "sum((sum(rate(container_cpu_system_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_kernelmode{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "System", - "refId": "B" - }, - { - "expr": "sum((sum(rate(container_cpu_usage_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Total", - "refId": "C" - }, - { - "expr": "sum((sum(rate(container_cpu_user_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_usermode{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "User", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "cpu", - "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": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum((sum(container_memory_working_set_bytes{namespace=~\"$namespace\"} OR windows_container_memory_usage_commit_bytes{namespace=~\"$namespace\"}) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Total", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Memory Utilization", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "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": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 7, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum((sum(irate(container_network_receive_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Receive Total", - "refId": "A" - }, - { - "expr": "sum((sum(irate(container_network_transmit_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Transmit Total", - "refId": "B" - }, - { - "expr": "sum((sum(irate(container_network_receive_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Receive Dropped", - "refId": "C" - }, - { - "expr": "sum((sum(irate(container_network_receive_errors_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Receive Errors", - "refId": "D" - }, - { - "expr": "sum((sum(irate(container_network_transmit_errors_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Transmit Errors", - "refId": "E" - }, - { - "expr": "sum((sum(irate(container_network_transmit_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Transmit Dropped", - "refId": "F" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network Traffic", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "pps", - "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": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum((sum(irate(container_network_receive_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Receive Total", - "refId": "A" - }, - { - "expr": "sum((sum(irate(container_network_transmit_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Transmit Total", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Network I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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": { - "{{pod}}": "#3797d5" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 7 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "percentage": false, - "pluginVersion": "7.1.5", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum((sum(rate(container_fs_writes_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Write", - "refId": "A" - }, - { - "expr": "sum((sum(rate(container_fs_reads_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", - "interval": "", - "legendFormat": "Read", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": 1, - "format": "Bps", - "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 - } - } - ], - "refresh": false, - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "query": "query_result(kube_pod_info{namespace!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", - "refresh": 2, - "regex": "/.*namespace=\"([^\"]*)\"/", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "kind", - "query": "query_result(kube_pod_info{namespace=\"$namespace\", created_by_kind!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", - "refresh": 2, - "regex": "/.*created_by_kind=\"([^\"]*)\"/", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "workload", - "query": "query_result(kube_pod_info{namespace=\"$namespace\", created_by_kind=\"$kind\", created_by_name!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", - "refresh": 2, - "regex": "/.*created_by_name=\"([^\"]*)\"/", - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Rancher / Workload", - "uid": "rancher-workload-1", - "version": 8 -} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/upgrade/scripts/delete-workloads-with-old-labels.sh b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/upgrade/scripts/delete-workloads-with-old-labels.sh deleted file mode 100644 index 89431e7132..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/files/upgrade/scripts/delete-workloads-with-old-labels.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -e -set -x - -# node-exporter -kubectl delete daemonset -l app=prometheus-node-exporter,release=rancher-monitoring --ignore-not-found=true - -# prometheus-adapter -kubectl delete deployments -l app=prometheus-adapter,release=rancher-monitoring --ignore-not-found=true - -# kube-state-metrics -kubectl delete deployments -l app.kubernetes.io/instance=rancher-monitoring,app.kubernetes.io/name=kube-state-metrics --cascade=orphan --ignore-not-found=true -kubectl delete statefulsets -l app.kubernetes.io/instance=rancher-monitoring,app.kubernetes.io/name=kube-state-metrics --cascade=orphan --ignore-not-found=true diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/NOTES.txt deleted file mode 100644 index 371f3ae398..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/NOTES.txt +++ /dev/null @@ -1,4 +0,0 @@ -{{ $.Chart.Name }} has been installed. Check its status by running: - kubectl --namespace {{ template "kube-prometheus-stack.namespace" . }} get pods -l "release={{ $.Release.Name }}" - -Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator. diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/_helpers.tpl deleted file mode 100644 index 0ca1fcd195..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/_helpers.tpl +++ /dev/null @@ -1,464 +0,0 @@ -# Rancher -{{- define "system_default_registry" -}} -{{- if .Values.global.cattle.systemDefaultRegistry -}} -{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} -{{- end -}} -{{- end -}} - -{{- define "monitoring_registry" -}} - {{- $temp_registry := (include "system_default_registry" .) -}} - {{- if $temp_registry -}} - {{- trimSuffix "/" $temp_registry -}} - {{- else -}} - {{- .Values.global.imageRegistry -}} - {{- end -}} -{{- end -}} - -{{/* -https://github.com/helm/helm/issues/4535#issuecomment-477778391 -Usage: {{ include "call-nested" (list . "SUBCHART_NAME" "TEMPLATE") }} -e.g. {{ include "call-nested" (list . "grafana" "grafana.fullname") }} -*/}} -{{- define "call-nested" }} -{{- $dot := index . 0 }} -{{- $subchart := index . 1 | splitList "." }} -{{- $template := index . 2 }} -{{- $values := $dot.Values }} -{{- range $subchart }} -{{- $values = index $values . }} -{{- end }} -{{- include $template (dict "Chart" (dict "Name" (last $subchart)) "Values" $values "Release" $dot.Release "Capabilities" $dot.Capabilities) }} -{{- end }} - -# Special Exporters -{{- define "exporter.kubeEtcd.enabled" -}} -{{- if or .Values.kubeEtcd.enabled .Values.rkeEtcd.enabled .Values.kubeAdmEtcd.enabled .Values.rke2Etcd.enabled -}} -"true" -{{- end -}} -{{- end }} - -{{- define "exporter.kubeControllerManager.enabled" -}} -{{- if or .Values.kubeControllerManager.enabled .Values.rkeControllerManager.enabled .Values.k3sServer.enabled .Values.kubeAdmControllerManager.enabled .Values.rke2ControllerManager.enabled -}} -"true" -{{- end -}} -{{- end }} - -{{- define "exporter.kubeScheduler.enabled" -}} -{{- if or .Values.kubeScheduler.enabled .Values.rkeScheduler.enabled .Values.k3sServer.enabled .Values.kubeAdmScheduler.enabled .Values.rke2Scheduler.enabled -}} -"true" -{{- end -}} -{{- end }} - -{{- define "exporter.kubeProxy.enabled" -}} -{{- if or .Values.kubeProxy.enabled .Values.rkeProxy.enabled .Values.k3sServer.enabled .Values.kubeAdmProxy.enabled .Values.rke2Proxy.enabled -}} -"true" -{{- end -}} -{{- end }} - -{{- define "exporter.kubelet.enabled" -}} -{{- if or .Values.kubelet.enabled .Values.hardenedKubelet.enabled .Values.k3sServer.enabled -}} -"true" -{{- end -}} -{{- end }} - -{{- define "exporter.kubeControllerManager.jobName" -}} -{{- if .Values.k3sServer.enabled -}} -k3s-server -{{- else -}} -kube-controller-manager -{{- end -}} -{{- end }} - -{{- define "exporter.kubeScheduler.jobName" -}} -{{- if .Values.k3sServer.enabled -}} -k3s-server -{{- else -}} -kube-scheduler -{{- end -}} -{{- end }} - -{{- define "exporter.kubeProxy.jobName" -}} -{{- if .Values.k3sServer.enabled -}} -k3s-server -{{- else -}} -kube-proxy -{{- end -}} -{{- end }} - -{{- define "exporter.kubelet.jobName" -}} -{{- if .Values.k3sServer.enabled -}} -k3s-server -{{- else -}} -kubelet -{{- end -}} -{{- end }} - -{{- define "kubelet.serviceMonitor.resourcePath" -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if not (eq .Values.kubelet.serviceMonitor.resourcePath "/metrics/resource/v1alpha1") -}} -{{ .Values.kubelet.serviceMonitor.resourcePath }} -{{- else if semverCompare ">=1.20.0-0" $kubeTargetVersion -}} -/metrics/resource -{{- else -}} -/metrics/resource/v1alpha1 -{{- end -}} -{{- end }} - -{{- define "rancher.serviceMonitor.selector" -}} -{{- if .Values.rancherMonitoring.selector }} -{{ .Values.rancherMonitoring.selector | toYaml }} -{{- else }} -{{- $rancherDeployment := (lookup "apps/v1" "Deployment" "cattle-system" "rancher") }} -{{- if $rancherDeployment }} -matchLabels: - app: rancher - chart: {{ index $rancherDeployment.metadata.labels "chart" }} - release: rancher -{{- end }} -{{- end }} -{{- end }} - -# Windows Support - -{{/* -Windows cluster will add default taint for linux nodes, -add below linux tolerations to workloads could be scheduled to those linux nodes -*/}} - -{{- define "linux-node-tolerations" -}} -- key: "cattle.io/os" - value: "linux" - effect: "NoSchedule" - operator: "Equal" -{{- end -}} - -{{- define "linux-node-selector" -}} -{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} -beta.kubernetes.io/os: linux -{{- else -}} -kubernetes.io/os: linux -{{- end -}} -{{- end -}} - -# Prometheus Operator - -{{/* vim: set filetype=mustache: */}} -{{/* Expand the name of the chart. This is suffixed with -alertmanager, which means subtract 13 from longest 63 available */}} -{{- define "kube-prometheus-stack.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 50 | 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. -The components in this chart create additional resources that expand the longest created name strings. -The longest name that gets created adds and extra 37 characters, so truncation should be 63-35=26. -*/}} -{{- define "kube-prometheus-stack.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 26 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 26 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 26 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* Fullname suffixed with -operator */}} -{{/* Adding 9 to 26 truncation of kube-prometheus-stack.fullname */}} -{{- define "kube-prometheus-stack.operator.fullname" -}} -{{- if .Values.prometheusOperator.fullnameOverride -}} -{{- .Values.prometheusOperator.fullnameOverride | trunc 35 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-operator" (include "kube-prometheus-stack.fullname" .) -}} -{{- end }} -{{- end }} - -{{/* Prometheus custom resource instance name */}} -{{- define "kube-prometheus-stack.prometheus.crname" -}} -{{- if .Values.cleanPrometheusOperatorObjectNames }} -{{- include "kube-prometheus-stack.fullname" . }} -{{- else }} -{{- print (include "kube-prometheus-stack.fullname" .) "-prometheus" }} -{{- end }} -{{- end }} - -{{/* Prometheus apiVersion for networkpolicy */}} -{{- define "kube-prometheus-stack.prometheus.networkPolicy.apiVersion" -}} -{{- print "networking.k8s.io/v1" -}} -{{- end }} - -{{/* Alertmanager custom resource instance name */}} -{{- define "kube-prometheus-stack.alertmanager.crname" -}} -{{- if .Values.cleanPrometheusOperatorObjectNames }} -{{- include "kube-prometheus-stack.fullname" . }} -{{- else }} -{{- print (include "kube-prometheus-stack.fullname" .) "-alertmanager" -}} -{{- end }} -{{- end }} - -{{/* ThanosRuler custom resource instance name */}} -{{/* Subtracting 1 from 26 truncation of kube-prometheus-stack.fullname */}} -{{- define "kube-prometheus-stack.thanosRuler.crname" -}} -{{- if .Values.cleanPrometheusOperatorObjectNames }} -{{- include "kube-prometheus-stack.fullname" . }} -{{- else }} -{{- print (include "kube-prometheus-stack.fullname" . | trunc 25 | trimSuffix "-") "-thanos-ruler" -}} -{{- end }} -{{- end }} - -{{/* Shortened name suffixed with thanos-ruler */}} -{{- define "kube-prometheus-stack.thanosRuler.name" -}} -{{- default (printf "%s-thanos-ruler" (include "kube-prometheus-stack.name" .)) .Values.thanosRuler.name -}} -{{- end }} - - -{{/* Create chart name and version as used by the chart label. */}} -{{- define "kube-prometheus-stack.chartref" -}} -{{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} -{{- end }} - -{{/* Generate basic labels */}} -{{- define "kube-prometheus-stack.labels" }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -app.kubernetes.io/instance: {{ .Release.Name }} -app.kubernetes.io/version: "{{ replace "+" "_" .Chart.Version }}" -app.kubernetes.io/part-of: {{ template "kube-prometheus-stack.name" . }} -chart: {{ template "kube-prometheus-stack.chartref" . }} -release: {{ $.Release.Name | quote }} -heritage: {{ $.Release.Service | quote }} -{{- if .Values.commonLabels}} -{{ toYaml .Values.commonLabels }} -{{- end }} -{{- end }} - -{{/* Create the name of kube-prometheus-stack service account to use */}} -{{- define "kube-prometheus-stack.operator.serviceAccountName" -}} -{{- if .Values.prometheusOperator.serviceAccount.create -}} - {{ default (include "kube-prometheus-stack.operator.fullname" .) .Values.prometheusOperator.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.prometheusOperator.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* Create the name of kube-prometheus-stack service account to use */}} -{{- define "kube-prometheus-stack.operator.admissionWebhooks.serviceAccountName" -}} -{{- if .Values.prometheusOperator.serviceAccount.create -}} - {{ default (printf "%s-webhook" (include "kube-prometheus-stack.operator.fullname" .)) .Values.prometheusOperator.admissionWebhooks.deployment.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.prometheusOperator.admissionWebhooks.deployment.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* Create the name of prometheus service account to use */}} -{{- define "kube-prometheus-stack.prometheus.serviceAccountName" -}} -{{- if .Values.prometheus.serviceAccount.create -}} - {{ default (print (include "kube-prometheus-stack.fullname" .) "-prometheus") .Values.prometheus.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.prometheus.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* Create the name of alertmanager service account to use */}} -{{- define "kube-prometheus-stack.alertmanager.serviceAccountName" -}} -{{- if .Values.alertmanager.serviceAccount.create -}} - {{ default (print (include "kube-prometheus-stack.fullname" .) "-alertmanager") .Values.alertmanager.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.alertmanager.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* Create the name of thanosRuler service account to use */}} -{{- define "kube-prometheus-stack.thanosRuler.serviceAccountName" -}} -{{- if .Values.thanosRuler.serviceAccount.create -}} - {{ default (include "kube-prometheus-stack.thanosRuler.name" .) .Values.thanosRuler.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.thanosRuler.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* -Allow the release namespace to be overridden for multi-namespace deployments in combined charts -*/}} -{{- define "kube-prometheus-stack.namespace" -}} - {{- if .Values.namespaceOverride -}} - {{- .Values.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{/* -Use the grafana namespace override for multi-namespace deployments in combined charts -*/}} -{{- define "kube-prometheus-stack-grafana.namespace" -}} - {{- if .Values.grafana.namespaceOverride -}} - {{- .Values.grafana.namespaceOverride -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{/* -Allow kube-state-metrics job name to be overridden -*/}} -{{- define "kube-prometheus-stack-kube-state-metrics.name" -}} - {{- if index .Values "kube-state-metrics" "nameOverride" -}} - {{- index .Values "kube-state-metrics" "nameOverride" -}} - {{- else -}} - {{- print "kube-state-metrics" -}} - {{- end -}} -{{- end -}} - -{{/* -Use the kube-state-metrics namespace override for multi-namespace deployments in combined charts -*/}} -{{- define "kube-prometheus-stack-kube-state-metrics.namespace" -}} - {{- if index .Values "kube-state-metrics" "namespaceOverride" -}} - {{- index .Values "kube-state-metrics" "namespaceOverride" -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{/* -Use the prometheus-node-exporter namespace override for multi-namespace deployments in combined charts -*/}} -{{- define "kube-prometheus-stack-prometheus-node-exporter.namespace" -}} - {{- if index .Values "prometheus-node-exporter" "namespaceOverride" -}} - {{- index .Values "prometheus-node-exporter" "namespaceOverride" -}} - {{- else -}} - {{- .Release.Namespace -}} - {{- end -}} -{{- end -}} - -{{/* Allow KubeVersion to be overridden. */}} -{{- define "kube-prometheus-stack.kubeVersion" -}} - {{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}} -{{- end -}} - -{{/* Get Ingress API Version */}} -{{- define "kube-prometheus-stack.ingress.apiVersion" -}} - {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" (include "kube-prometheus-stack.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 -}} - -{{/* Check Ingress stability */}} -{{- define "kube-prometheus-stack.ingress.isStable" -}} - {{- eq (include "kube-prometheus-stack.ingress.apiVersion" .) "networking.k8s.io/v1" -}} -{{- end -}} - -{{/* Check Ingress supports pathType */}} -{{/* pathType was added to networking.k8s.io/v1beta1 in Kubernetes 1.18 */}} -{{- define "kube-prometheus-stack.ingress.supportsPathType" -}} - {{- or (eq (include "kube-prometheus-stack.ingress.isStable" .) "true") (and (eq (include "kube-prometheus-stack.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" (include "kube-prometheus-stack.kubeVersion" .))) -}} -{{- end -}} - -{{/* Get Policy API Version */}} -{{- define "kube-prometheus-stack.pdb.apiVersion" -}} - {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">= 1.21-0" (include "kube-prometheus-stack.kubeVersion" .)) -}} - {{- print "policy/v1" -}} - {{- else -}} - {{- print "policy/v1beta1" -}} - {{- end -}} - {{- end -}} - -{{/* Get value based on current Kubernetes version */}} -{{- define "kube-prometheus-stack.kubeVersionDefaultValue" -}} - {{- $values := index . 0 -}} - {{- $kubeVersion := index . 1 -}} - {{- $old := index . 2 -}} - {{- $new := index . 3 -}} - {{- $default := index . 4 -}} - {{- if kindIs "invalid" $default -}} - {{- if semverCompare $kubeVersion (include "kube-prometheus-stack.kubeVersion" $values) -}} - {{- print $new -}} - {{- else -}} - {{- print $old -}} - {{- end -}} - {{- else -}} - {{- print $default }} - {{- end -}} -{{- end -}} - -{{/* Get value for kube-controller-manager depending on insecure scraping availability */}} -{{- define "kube-prometheus-stack.kubeControllerManager.insecureScrape" -}} - {{- $values := index . 0 -}} - {{- $insecure := index . 1 -}} - {{- $secure := index . 2 -}} - {{- $userValue := index . 3 -}} - {{- include "kube-prometheus-stack.kubeVersionDefaultValue" (list $values ">= 1.22-0" $insecure $secure $userValue) -}} -{{- end -}} - -{{/* Get value for kube-scheduler depending on insecure scraping availability */}} -{{- define "kube-prometheus-stack.kubeScheduler.insecureScrape" -}} - {{- $values := index . 0 -}} - {{- $insecure := index . 1 -}} - {{- $secure := index . 2 -}} - {{- $userValue := index . 3 -}} - {{- include "kube-prometheus-stack.kubeVersionDefaultValue" (list $values ">= 1.23-0" $insecure $secure $userValue) -}} -{{- end -}} - -{{/* Sets default scrape limits for servicemonitor */}} -{{- define "servicemonitor.scrapeLimits" -}} -{{- with .sampleLimit }} -sampleLimit: {{ . }} -{{- end }} -{{- with .targetLimit }} -targetLimit: {{ . }} -{{- end }} -{{- with .labelLimit }} -labelLimit: {{ . }} -{{- end }} -{{- with .labelNameLengthLimit }} -labelNameLengthLimit: {{ . }} -{{- end }} -{{- with .labelValueLengthLimit }} -labelValueLengthLimit: {{ . }} -{{- end }} -{{- end -}} - -{{/* -To help compatibility with other charts which use global.imagePullSecrets. -Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). -global: - imagePullSecrets: - - name: pullSecret1 - - name: pullSecret2 - -or - -global: - imagePullSecrets: - - pullSecret1 - - pullSecret2 -*/}} -{{- define "kube-prometheus-stack.imagePullSecrets" -}} -{{- range .Values.global.imagePullSecrets }} - {{- if eq (typeOf .) "map[string]interface {}" }} -- {{ toYaml . | trim }} - {{- else }} -- name: {{ . }} - {{- end }} -{{- end }} -{{- end -}} - -{{- define "kube-prometheus-stack.operator.admission-webhook.dnsNames" }} -{{- $fullname := include "kube-prometheus-stack.operator.fullname" . }} -{{- $namespace := include "kube-prometheus-stack.namespace" . }} -{{- $fullname }} -{{ $fullname }}.{{ $namespace }}.svc -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.enabled }} -{{ $fullname }}-webhook -{{ $fullname }}-webhook.{{ $namespace }}.svc -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/alertmanager.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/alertmanager.yaml deleted file mode 100644 index fdc9a8af61..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/alertmanager.yaml +++ /dev/null @@ -1,195 +0,0 @@ -{{- if .Values.alertmanager.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: Alertmanager -metadata: - name: {{ template "kube-prometheus-stack.alertmanager.crname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.alertmanager.annotations }} - annotations: -{{ toYaml .Values.alertmanager.annotations | indent 4 }} -{{- end }} -spec: -{{- if .Values.alertmanager.alertmanagerSpec.image }} - {{- $registry := include "monitoring_registry" . | default .Values.alertmanager.alertmanagerSpec.image.registry }} - {{- if and .Values.alertmanager.alertmanagerSpec.image.tag .Values.alertmanager.alertmanagerSpec.image.sha }} - image: "{{ $registry }}/{{ .Values.alertmanager.alertmanagerSpec.image.repository }}:{{ .Values.alertmanager.alertmanagerSpec.image.tag }}@sha256:{{ .Values.alertmanager.alertmanagerSpec.image.sha }}" - {{- else if .Values.alertmanager.alertmanagerSpec.image.sha }} - image: "{{ $registry }}/{{ .Values.alertmanager.alertmanagerSpec.image.repository }}@sha256:{{ .Values.alertmanager.alertmanagerSpec.image.sha }}" - {{- else if .Values.alertmanager.alertmanagerSpec.image.tag }} - image: "{{ $registry }}/{{ .Values.alertmanager.alertmanagerSpec.image.repository }}:{{ .Values.alertmanager.alertmanagerSpec.image.tag }}" - {{- else }} - image: "{{ $registry }}/{{ .Values.alertmanager.alertmanagerSpec.image.repository }}" - {{- end }} - version: {{ default .Values.alertmanager.alertmanagerSpec.image.tag .Values.alertmanager.alertmanagerSpec.version }} - {{- if .Values.alertmanager.alertmanagerSpec.image.sha }} - sha: {{ .Values.alertmanager.alertmanagerSpec.image.sha }} - {{- end }} -{{- end }} - replicas: {{ .Values.alertmanager.alertmanagerSpec.replicas }} - listenLocal: {{ .Values.alertmanager.alertmanagerSpec.listenLocal }} - serviceAccountName: {{ template "kube-prometheus-stack.alertmanager.serviceAccountName" . }} - automountServiceAccountToken: {{ .Values.alertmanager.alertmanagerSpec.automountServiceAccountToken }} -{{- if .Values.alertmanager.alertmanagerSpec.externalUrl }} - externalUrl: "{{ tpl .Values.alertmanager.alertmanagerSpec.externalUrl . }}" -{{- else if and .Values.alertmanager.ingress.enabled .Values.alertmanager.ingress.hosts }} - externalUrl: "http://{{ tpl (index .Values.alertmanager.ingress.hosts 0) . }}{{ .Values.alertmanager.alertmanagerSpec.routePrefix }}" -{{- else if not (or (kindIs "invalid" .Values.global.cattle.url) (kindIs "invalid" .Values.global.cattle.clusterId)) }} - externalUrl: "{{ .Values.global.cattle.url }}/k8s/clusters/{{ .Values.global.cattle.clusterId }}/api/v1/namespaces/{{ .Values.namespaceOverride }}/services/http:{{ template "kube-prometheus-stack.fullname" . }}-alertmanager:{{ .Values.alertmanager.service.port }}/proxy" -{{- else }} - externalUrl: http://{{ template "kube-prometheus-stack.fullname" . }}-alertmanager.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.alertmanager.service.port }} -{{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 4 }} -{{- if .Values.alertmanager.alertmanagerSpec.nodeSelector }} -{{ toYaml .Values.alertmanager.alertmanagerSpec.nodeSelector | indent 4 }} -{{- end }} - paused: {{ .Values.alertmanager.alertmanagerSpec.paused }} - logFormat: {{ .Values.alertmanager.alertmanagerSpec.logFormat | quote }} - logLevel: {{ .Values.alertmanager.alertmanagerSpec.logLevel | quote }} - retention: {{ .Values.alertmanager.alertmanagerSpec.retention | quote }} - {{- with .Values.alertmanager.enableFeatures }} - enableFeatures: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.secrets }} - secrets: -{{ toYaml .Values.alertmanager.alertmanagerSpec.secrets | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.configSecret }} - configSecret: {{ .Values.alertmanager.alertmanagerSpec.configSecret }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.configMaps }} - configMaps: -{{ toYaml .Values.alertmanager.alertmanagerSpec.configMaps | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.alertmanagerConfigSelector }} - alertmanagerConfigSelector: -{{ tpl (toYaml .Values.alertmanager.alertmanagerSpec.alertmanagerConfigSelector | indent 4) . }} -{{ else }} - alertmanagerConfigSelector: {} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.alertmanagerConfigNamespaceSelector }} - alertmanagerConfigNamespaceSelector: -{{ tpl (toYaml .Values.alertmanager.alertmanagerSpec.alertmanagerConfigNamespaceSelector | indent 4) . }} -{{ else }} - alertmanagerConfigNamespaceSelector: {} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.web }} - web: -{{ toYaml .Values.alertmanager.alertmanagerSpec.web | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.alertmanagerConfiguration }} - alertmanagerConfiguration: -{{ toYaml .Values.alertmanager.alertmanagerSpec.alertmanagerConfiguration | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.alertmanagerConfigMatcherStrategy }} - alertmanagerConfigMatcherStrategy: -{{ toYaml .Values.alertmanager.alertmanagerSpec.alertmanagerConfigMatcherStrategy | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.resources }} - resources: -{{ toYaml .Values.alertmanager.alertmanagerSpec.resources | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.routePrefix }} - routePrefix: "{{ .Values.alertmanager.alertmanagerSpec.routePrefix }}" -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.securityContext }} - securityContext: -{{ toYaml .Values.alertmanager.alertmanagerSpec.securityContext | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.storage }} - storage: -{{ tpl (toYaml .Values.alertmanager.alertmanagerSpec.storage | indent 4) . }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.podMetadata }} - podMetadata: -{{ toYaml .Values.alertmanager.alertmanagerSpec.podMetadata | indent 4 }} -{{- end }} -{{- if or .Values.alertmanager.alertmanagerSpec.podAntiAffinity .Values.alertmanager.alertmanagerSpec.affinity }} - affinity: -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.affinity }} -{{ toYaml .Values.alertmanager.alertmanagerSpec.affinity | indent 4 }} -{{- end }} -{{- if eq .Values.alertmanager.alertmanagerSpec.podAntiAffinity "hard" }} - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - topologyKey: {{ .Values.alertmanager.alertmanagerSpec.podAntiAffinityTopologyKey }} - labelSelector: - matchExpressions: - - {key: app.kubernetes.io/name, operator: In, values: [alertmanager]} - - {key: alertmanager, operator: In, values: [{{ template "kube-prometheus-stack.alertmanager.crname" . }}]} -{{- else if eq .Values.alertmanager.alertmanagerSpec.podAntiAffinity "soft" }} - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - topologyKey: {{ .Values.alertmanager.alertmanagerSpec.podAntiAffinityTopologyKey }} - labelSelector: - matchExpressions: - - {key: app.kubernetes.io/name, operator: In, values: [alertmanager]} - - {key: alertmanager, operator: In, values: [{{ template "kube-prometheus-stack.alertmanager.crname" . }}]} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 4 }} -{{- if .Values.alertmanager.alertmanagerSpec.tolerations }} -{{ toYaml .Values.alertmanager.alertmanagerSpec.tolerations | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.topologySpreadConstraints }} - topologySpreadConstraints: -{{ toYaml .Values.alertmanager.alertmanagerSpec.topologySpreadConstraints | indent 4 }} -{{- end }} -{{- if .Values.global.imagePullSecrets }} - imagePullSecrets: -{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.containers }} - containers: -{{ toYaml .Values.alertmanager.alertmanagerSpec.containers | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.initContainers }} - initContainers: -{{ toYaml .Values.alertmanager.alertmanagerSpec.initContainers | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.priorityClassName }} - priorityClassName: {{.Values.alertmanager.alertmanagerSpec.priorityClassName }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.additionalPeers }} - additionalPeers: -{{ toYaml .Values.alertmanager.alertmanagerSpec.additionalPeers | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.volumes }} - volumes: -{{ toYaml .Values.alertmanager.alertmanagerSpec.volumes | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.volumeMounts }} - volumeMounts: -{{ toYaml .Values.alertmanager.alertmanagerSpec.volumeMounts | indent 4 }} -{{- end }} - portName: {{ .Values.alertmanager.alertmanagerSpec.portName }} -{{- if .Values.alertmanager.alertmanagerSpec.clusterAdvertiseAddress }} - clusterAdvertiseAddress: {{ .Values.alertmanager.alertmanagerSpec.clusterAdvertiseAddress }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.clusterGossipInterval }} - clusterGossipInterval: {{ .Values.alertmanager.alertmanagerSpec.clusterGossipInterval }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.clusterPeerTimeout }} - clusterPeerTimeout: {{ .Values.alertmanager.alertmanagerSpec.clusterPeerTimeout }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.clusterPushpullInterval }} - clusterPushpullInterval: {{ .Values.alertmanager.alertmanagerSpec.clusterPushpullInterval }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.forceEnableClusterMode }} - forceEnableClusterMode: {{ .Values.alertmanager.alertmanagerSpec.forceEnableClusterMode }} -{{- end }} -{{- if .Values.alertmanager.alertmanagerSpec.minReadySeconds }} - minReadySeconds: {{ .Values.alertmanager.alertmanagerSpec.minReadySeconds }} -{{- end }} -{{- with .Values.alertmanager.alertmanagerSpec.additionalConfig }} - {{- tpl (toYaml .) $ | nindent 2 }} -{{- end }} -{{- with .Values.alertmanager.alertmanagerSpec.additionalConfigString }} - {{- tpl . $ | nindent 2 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/extrasecret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/extrasecret.yaml deleted file mode 100644 index ecd8f47021..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/extrasecret.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.alertmanager.extraSecret.data -}} -{{- $secretName := printf "alertmanager-%s-extra" (include "kube-prometheus-stack.fullname" . ) -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ default $secretName .Values.alertmanager.extraSecret.name }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- if .Values.alertmanager.extraSecret.annotations }} - annotations: -{{ toYaml .Values.alertmanager.extraSecret.annotations | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager - app.kubernetes.io/component: alertmanager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: -{{- range $key, $val := .Values.alertmanager.extraSecret.data }} - {{ $key }}: {{ $val | b64enc | quote }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/ingress.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/ingress.yaml deleted file mode 100644 index be9f5aa279..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/ingress.yaml +++ /dev/null @@ -1,78 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.ingress.enabled }} -{{- $pathType := .Values.alertmanager.ingress.pathType | default "ImplementationSpecific" }} -{{- $serviceName := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "alertmanager" }} -{{- $backendServiceName := .Values.alertmanager.ingress.serviceName | default (printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "alertmanager") }} -{{- $servicePort := .Values.alertmanager.ingress.servicePort | default .Values.alertmanager.service.port -}} -{{- $routePrefix := list .Values.alertmanager.alertmanagerSpec.routePrefix }} -{{- $paths := .Values.alertmanager.ingress.paths | default $routePrefix -}} -{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} -{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} -apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" . }} -kind: Ingress -metadata: - name: {{ $serviceName }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- if .Values.alertmanager.ingress.annotations }} - annotations: - {{- tpl (toYaml .Values.alertmanager.ingress.annotations) . | nindent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager -{{- if .Values.alertmanager.ingress.labels }} -{{ toYaml .Values.alertmanager.ingress.labels | indent 4 }} -{{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - {{- if $apiIsStable }} - {{- if .Values.alertmanager.ingress.ingressClassName }} - ingressClassName: {{ .Values.alertmanager.ingress.ingressClassName }} - {{- end }} - {{- end }} - rules: - {{- if .Values.alertmanager.ingress.hosts }} - {{- range $host := .Values.alertmanager.ingress.hosts }} - - host: {{ tpl $host $ | quote }} - http: - paths: - {{- range $p := $paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ $backendServiceName }} - port: - number: {{ $servicePort }} - {{- else }} - serviceName: {{ $backendServiceName }} - servicePort: {{ $servicePort }} - {{- end }} - {{- end -}} - {{- end -}} - {{- else }} - - http: - paths: - {{- range $p := $paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ $backendServiceName }} - port: - number: {{ $servicePort }} - {{- else }} - serviceName: {{ $backendServiceName }} - servicePort: {{ $servicePort }} - {{- end }} - {{- end -}} - {{- end -}} - {{- if .Values.alertmanager.ingress.tls }} - tls: -{{ tpl (toYaml .Values.alertmanager.ingress.tls | indent 4) . }} - {{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/ingressperreplica.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/ingressperreplica.yaml deleted file mode 100644 index b2e00a4162..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/ingressperreplica.yaml +++ /dev/null @@ -1,67 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.servicePerReplica.enabled .Values.alertmanager.ingressPerReplica.enabled }} -{{- $pathType := .Values.alertmanager.ingressPerReplica.pathType | default "" }} -{{- $count := .Values.alertmanager.alertmanagerSpec.replicas | int -}} -{{- $servicePort := .Values.alertmanager.service.port -}} -{{- $ingressValues := .Values.alertmanager.ingressPerReplica -}} -{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} -{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} -apiVersion: v1 -kind: List -metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-ingressperreplica - namespace: {{ template "kube-prometheus-stack.namespace" . }} -items: -{{ range $i, $e := until $count }} - - kind: Ingress - apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" $ }} - metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-{{ $i }} - namespace: {{ template "kube-prometheus-stack.namespace" $ }} - labels: - app: {{ include "kube-prometheus-stack.name" $ }}-alertmanager - {{ include "kube-prometheus-stack.labels" $ | indent 8 }} - {{- if $ingressValues.labels }} -{{ toYaml $ingressValues.labels | indent 8 }} - {{- end }} - {{- if $ingressValues.annotations }} - annotations: - {{- tpl (toYaml $ingressValues.annotations) $ | nindent 8 }} - {{- end }} - spec: - {{- if $apiIsStable }} - {{- if $ingressValues.ingressClassName }} - ingressClassName: {{ $ingressValues.ingressClassName }} - {{- end }} - {{- end }} - rules: - - host: {{ $ingressValues.hostPrefix }}-{{ $i }}.{{ $ingressValues.hostDomain }} - http: - paths: - {{- range $p := $ingressValues.paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-{{ $i }} - port: - number: {{ $servicePort }} - {{- else }} - serviceName: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-{{ $i }} - servicePort: {{ $servicePort }} - {{- end }} - {{- end -}} - {{- if or $ingressValues.tlsSecretName $ingressValues.tlsSecretPerReplica.enabled }} - tls: - - hosts: - - {{ $ingressValues.hostPrefix }}-{{ $i }}.{{ $ingressValues.hostDomain }} - {{- if $ingressValues.tlsSecretPerReplica.enabled }} - secretName: {{ $ingressValues.tlsSecretPerReplica.prefix }}-{{ $i }} - {{- else }} - secretName: {{ $ingressValues.tlsSecretName }} - {{- end }} - {{- end }} -{{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/podDisruptionBudget.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/podDisruptionBudget.yaml deleted file mode 100644 index b183403125..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/podDisruptionBudget.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.podDisruptionBudget.enabled }} -apiVersion: {{ include "kube-prometheus-stack.pdb.apiVersion" . }} -kind: PodDisruptionBudget -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - {{- if .Values.alertmanager.podDisruptionBudget.minAvailable }} - minAvailable: {{ .Values.alertmanager.podDisruptionBudget.minAvailable }} - {{- end }} - {{- if .Values.alertmanager.podDisruptionBudget.maxUnavailable }} - maxUnavailable: {{ .Values.alertmanager.podDisruptionBudget.maxUnavailable }} - {{- end }} - selector: - matchLabels: - app.kubernetes.io/name: alertmanager - alertmanager: {{ template "kube-prometheus-stack.alertmanager.crname" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp-role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp-role.yaml deleted file mode 100644 index e8da52e0f4..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp-role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -rules: -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} -- apiGroups: ['policy'] -{{- else }} -- apiGroups: ['extensions'] -{{- end }} - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "kube-prometheus-stack.fullname" . }}-alertmanager -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp-rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp-rolebinding.yaml deleted file mode 100644 index 71a8ec41dc..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp-rolebinding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager -subjects: - - kind: ServiceAccount - name: {{ template "kube-prometheus-stack.alertmanager.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp.yaml deleted file mode 100644 index 5a940afab6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/psp.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager -{{- if .Values.global.rbac.pspAnnotations }} - annotations: -{{ toYaml .Values.global.rbac.pspAnnotations | indent 4 }} -{{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - privileged: false - # Allow core volume types. - volumes: - - 'configMap' - - 'emptyDir' - - 'projected' - - 'secret' - - 'downwardAPI' - - 'persistentVolumeClaim' - hostNetwork: false - hostIPC: false - hostPID: false - runAsUser: - # Permits the container to run with root privileges as well. - rule: 'RunAsAny' - seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - readOnlyRootFilesystem: false -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/secret.yaml deleted file mode 100644 index d4c397fa43..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/secret.yaml +++ /dev/null @@ -1,37 +0,0 @@ -{{- if and (.Values.alertmanager.enabled) (not .Values.alertmanager.alertmanagerSpec.useExistingSecret) }} -{{/* This file is applied when the operation is helm install and the target secret does not exist. */}} -{{- $secretName := (printf "alertmanager-%s" (include "kube-prometheus-stack.alertmanager.crname" .)) }} -{{- if or (not (lookup "v1" "Secret" (include "kube-prometheus-stack.namespace" .) $secretName)) (eq .Values.alertmanager.secret.recreateIfExists true) }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ $secretName }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": pre-install, pre-upgrade - "helm.sh/hook-weight": "3" - "helm.sh/resource-policy": keep -{{- if .Values.alertmanager.secret.annotations }} - annotations: -{{ toYaml .Values.alertmanager.secret.annotations | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: -{{- if .Values.alertmanager.tplConfig }} -{{- if .Values.alertmanager.stringConfig }} - alertmanager.yaml: {{ tpl (.Values.alertmanager.stringConfig) . | b64enc | quote }} -{{- else if eq (typeOf .Values.alertmanager.config) "string" }} - alertmanager.yaml: {{ tpl (.Values.alertmanager.config) . | b64enc | quote }} -{{- else }} - alertmanager.yaml: {{ tpl (toYaml .Values.alertmanager.config) . | b64enc | quote }} -{{- end }} -{{- else }} - alertmanager.yaml: {{ toYaml .Values.alertmanager.config | b64enc | quote }} -{{- end }} -{{- range $key, $val := .Values.alertmanager.templateFiles }} - {{ $key }}: {{ $val | b64enc | quote }} -{{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/service.yaml deleted file mode 100644 index 858c83a4c3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/service.yaml +++ /dev/null @@ -1,72 +0,0 @@ -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if .Values.alertmanager.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager - self-monitor: {{ .Values.alertmanager.serviceMonitor.selfMonitor | quote }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.alertmanager.service.labels }} -{{ toYaml .Values.alertmanager.service.labels | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.service.annotations }} - annotations: -{{ toYaml .Values.alertmanager.service.annotations | indent 4 }} -{{- end }} -spec: -{{- if .Values.alertmanager.service.clusterIP }} - clusterIP: {{ .Values.alertmanager.service.clusterIP }} -{{- end }} -{{- if .Values.alertmanager.service.externalIPs }} - externalIPs: -{{ toYaml .Values.alertmanager.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.alertmanager.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.alertmanager.service.loadBalancerIP }} -{{- end }} -{{- if .Values.alertmanager.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.alertmanager.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} -{{- if ne .Values.alertmanager.service.type "ClusterIP" }} - externalTrafficPolicy: {{ .Values.alertmanager.service.externalTrafficPolicy }} -{{- end }} - ports: - - name: {{ .Values.alertmanager.alertmanagerSpec.portName }} - {{- if eq .Values.alertmanager.service.type "NodePort" }} - nodePort: {{ .Values.alertmanager.service.nodePort }} - {{- end }} - port: {{ .Values.alertmanager.service.port }} - targetPort: {{ .Values.alertmanager.service.targetPort }} - protocol: TCP - - name: reloader-web - {{- if semverCompare ">=1.20.0-0" $kubeTargetVersion }} - appProtocol: http - {{- end }} - port: 8080 - targetPort: reloader-web -{{- if .Values.alertmanager.service.additionalPorts }} -{{ toYaml .Values.alertmanager.service.additionalPorts | indent 2 }} -{{- end }} - selector: - app.kubernetes.io/name: alertmanager - alertmanager: {{ template "kube-prometheus-stack.alertmanager.crname" . }} -{{- if .Values.alertmanager.service.sessionAffinity }} - sessionAffinity: {{ .Values.alertmanager.service.sessionAffinity }} -{{- end }} -{{- if eq .Values.alertmanager.service.sessionAffinity "ClientIP" }} - sessionAffinityConfig: - clientIP: - timeoutSeconds: {{ .Values.alertmanager.service.sessionAffinityConfig.clientIP.timeoutSeconds }} -{{- end }} - type: "{{ .Values.alertmanager.service.type }}" -{{- if .Values.alertmanager.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.alertmanager.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.alertmanager.service.ipDualStack.ipFamilyPolicy }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/serviceaccount.yaml deleted file mode 100644 index 745ced8bde..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/serviceaccount.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.serviceAccount.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "kube-prometheus-stack.alertmanager.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager - app.kubernetes.io/name: {{ template "kube-prometheus-stack.name" . }}-alertmanager - app.kubernetes.io/component: alertmanager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.alertmanager.serviceAccount.annotations }} - annotations: -{{ toYaml .Values.alertmanager.serviceAccount.annotations | indent 4 }} -{{- end }} -automountServiceAccountToken: {{ .Values.alertmanager.serviceAccount.automountServiceAccountToken }} -{{- if .Values.global.imagePullSecrets }} -imagePullSecrets: -{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2}} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/servicemonitor.yaml deleted file mode 100644 index ffba880ae1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/servicemonitor.yaml +++ /dev/null @@ -1,84 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.serviceMonitor.selfMonitor }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- with .Values.alertmanager.serviceMonitor.additionalLabels }} -{{- toYaml . | nindent 4 }} -{{- end }} -spec: - {{- include "servicemonitor.scrapeLimits" .Values.alertmanager.serviceMonitor | nindent 2 }} - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-alertmanager - release: {{ $.Release.Name | quote }} - self-monitor: "true" - namespaceSelector: - matchNames: - - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} - endpoints: - - port: {{ .Values.alertmanager.alertmanagerSpec.portName }} - enableHttp2: {{ .Values.alertmanager.serviceMonitor.enableHttp2 }} - {{- if .Values.alertmanager.serviceMonitor.interval }} - interval: {{ .Values.alertmanager.serviceMonitor.interval }} - {{- end }} - {{- if .Values.alertmanager.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.alertmanager.serviceMonitor.proxyUrl}} - {{- end }} - {{- if .Values.alertmanager.serviceMonitor.scheme }} - scheme: {{ .Values.alertmanager.serviceMonitor.scheme }} - {{- end }} - {{- if .Values.alertmanager.serviceMonitor.bearerTokenFile }} - bearerTokenFile: {{ .Values.alertmanager.serviceMonitor.bearerTokenFile }} - {{- end }} - {{- if .Values.alertmanager.serviceMonitor.tlsConfig }} - tlsConfig: {{- toYaml .Values.alertmanager.serviceMonitor.tlsConfig | nindent 6 }} - {{- end }} - path: "{{ trimSuffix "/" .Values.alertmanager.alertmanagerSpec.routePrefix }}/metrics" - metricRelabelings: - {{- if .Values.alertmanager.serviceMonitor.metricRelabelings }} - {{- tpl (toYaml .Values.alertmanager.serviceMonitor.metricRelabelings | nindent 6) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName }} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} - {{- if .Values.alertmanager.serviceMonitor.relabelings }} - relabelings: {{- toYaml .Values.alertmanager.serviceMonitor.relabelings | nindent 6 }} - {{- end }} - {{- range .Values.alertmanager.serviceMonitor.additionalEndpoints }} - - port: {{ .port }} - {{- if or $.Values.alertmanager.serviceMonitor.interval .interval }} - interval: {{ default $.Values.alertmanager.serviceMonitor.interval .interval }} - {{- end }} - {{- if or $.Values.alertmanager.serviceMonitor.proxyUrl .proxyUrl }} - proxyUrl: {{ default $.Values.alertmanager.serviceMonitor.proxyUrl .proxyUrl }} - {{- end }} - {{- if or $.Values.alertmanager.serviceMonitor.scheme .scheme }} - scheme: {{ default $.Values.alertmanager.serviceMonitor.scheme .scheme }} - {{- end }} - {{- if or $.Values.alertmanager.serviceMonitor.bearerTokenFile .bearerTokenFile }} - bearerTokenFile: {{ default $.Values.alertmanager.serviceMonitor.bearerTokenFile .bearerTokenFile }} - {{- end }} - {{- if or $.Values.alertmanager.serviceMonitor.tlsConfig .tlsConfig }} - tlsConfig: {{- default $.Values.alertmanager.serviceMonitor.tlsConfig .tlsConfig | toYaml | nindent 6 }} - {{- end }} - path: {{ .path }} - {{- if or $.Values.alertmanager.serviceMonitor.metricRelabelings .metricRelabelings }} - metricRelabelings: {{- tpl (default $.Values.alertmanager.serviceMonitor.metricRelabelings .metricRelabelings | toYaml | nindent 6) . }} - {{- end }} - {{- if or $.Values.alertmanager.serviceMonitor.relabelings .relabelings }} - relabelings: {{- default $.Values.alertmanager.serviceMonitor.relabelings .relabelings | toYaml | nindent 6 }} - {{- end }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/serviceperreplica.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/serviceperreplica.yaml deleted file mode 100644 index 75a13bdf97..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/alertmanager/serviceperreplica.yaml +++ /dev/null @@ -1,49 +0,0 @@ -{{- if and .Values.alertmanager.enabled .Values.alertmanager.servicePerReplica.enabled }} -{{- $count := .Values.alertmanager.alertmanagerSpec.replicas | int -}} -{{- $serviceValues := .Values.alertmanager.servicePerReplica -}} -apiVersion: v1 -kind: List -metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-serviceperreplica - namespace: {{ template "kube-prometheus-stack.namespace" . }} -items: -{{- range $i, $e := until $count }} - - apiVersion: v1 - kind: Service - metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-{{ $i }} - namespace: {{ template "kube-prometheus-stack.namespace" $ }} - labels: - app: {{ include "kube-prometheus-stack.name" $ }}-alertmanager -{{ include "kube-prometheus-stack.labels" $ | indent 8 }} - {{- if $serviceValues.annotations }} - annotations: -{{ toYaml $serviceValues.annotations | indent 8 }} - {{- end }} - spec: - {{- if $serviceValues.clusterIP }} - clusterIP: {{ $serviceValues.clusterIP }} - {{- end }} - {{- if $serviceValues.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := $serviceValues.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} - {{- end }} - {{- if ne $serviceValues.type "ClusterIP" }} - externalTrafficPolicy: {{ $serviceValues.externalTrafficPolicy }} - {{- end }} - ports: - - name: {{ $.Values.alertmanager.alertmanagerSpec.portName }} - {{- if eq $serviceValues.type "NodePort" }} - nodePort: {{ $serviceValues.nodePort }} - {{- end }} - port: {{ $serviceValues.port }} - targetPort: {{ $serviceValues.targetPort }} - selector: - app.kubernetes.io/name: alertmanager - alertmanager: {{ template "kube-prometheus-stack.alertmanager.crname" $ }} - statefulset.kubernetes.io/pod-name: alertmanager-{{ include "kube-prometheus-stack.alertmanager.crname" $ }}-{{ $i }} - type: "{{ $serviceValues.type }}" -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/core-dns/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/core-dns/service.yaml deleted file mode 100644 index 5dedc369df..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/core-dns/service.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if and .Values.coreDns.enabled .Values.coreDns.service.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-coredns - labels: - app: {{ template "kube-prometheus-stack.name" . }}-coredns - jobLabel: coredns -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -spec: - clusterIP: None - {{- if .Values.coreDns.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.coreDns.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.coreDns.service.ipDualStack.ipFamilyPolicy }} - {{- end }} - ports: - - name: {{ .Values.coreDns.serviceMonitor.port }} - port: {{ .Values.coreDns.service.port }} - protocol: TCP - targetPort: {{ .Values.coreDns.service.targetPort }} - selector: - {{- if .Values.coreDns.service.selector }} -{{ toYaml .Values.coreDns.service.selector | indent 4 }} - {{- else}} - k8s-app: kube-dns - {{- end}} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/core-dns/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/core-dns/servicemonitor.yaml deleted file mode 100644 index dc15a06937..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/core-dns/servicemonitor.yaml +++ /dev/null @@ -1,58 +0,0 @@ -{{- if and .Values.coreDns.enabled .Values.coreDns.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-coredns - {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - namespace: kube-system - {{- else }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-coredns - {{- with .Values.coreDns.serviceMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - jobLabel: {{ .Values.coreDns.serviceMonitor.jobLabel }} - {{- include "servicemonitor.scrapeLimits" .Values.coreDns.serviceMonitor | nindent 2 }} - selector: - {{- if .Values.coreDns.serviceMonitor.selector }} - {{ tpl (toYaml .Values.coreDns.serviceMonitor.selector | nindent 4) . }} - {{- else }} - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-coredns - release: {{ $.Release.Name | quote }} - {{- end }} - namespaceSelector: - matchNames: - - "kube-system" - endpoints: - - port: {{ .Values.coreDns.serviceMonitor.port }} - {{- if .Values.coreDns.serviceMonitor.interval}} - interval: {{ .Values.coreDns.serviceMonitor.interval }} - {{- end }} - {{- if .Values.coreDns.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.coreDns.serviceMonitor.proxyUrl}} - {{- end }} - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - metricRelabelings: - {{- if .Values.coreDns.serviceMonitor.metricRelabelings }} - {{ tpl (toYaml .Values.coreDns.serviceMonitor.metricRelabelings | indent 4) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName }} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.coreDns.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.coreDns.serviceMonitor.relabelings | indent 4) . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-api-server/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-api-server/servicemonitor.yaml deleted file mode 100644 index 66e777632e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-api-server/servicemonitor.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- if and .Values.kubeApiServer.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-apiserver - {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - namespace: default - {{- else }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-apiserver - {{- with .Values.kubeApiServer.serviceMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - {{- include "servicemonitor.scrapeLimits" .Values.kubeApiServer.serviceMonitor | nindent 2 }} - endpoints: - - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - {{- if .Values.kubeApiServer.serviceMonitor.interval }} - interval: {{ .Values.kubeApiServer.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubeApiServer.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubeApiServer.serviceMonitor.proxyUrl }} - {{- end }} - port: https - scheme: https - metricRelabelings: - {{- if .Values.kubeApiServer.serviceMonitor.metricRelabelings }} -{{ tpl (toYaml .Values.kubeApiServer.serviceMonitor.metricRelabelings | indent 6) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.kubeApiServer.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.kubeApiServer.serviceMonitor.relabelings | indent 6) . }} -{{- end }} - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - serverName: {{ .Values.kubeApiServer.tlsConfig.serverName }} - insecureSkipVerify: {{ .Values.kubeApiServer.tlsConfig.insecureSkipVerify }} - jobLabel: {{ .Values.kubeApiServer.serviceMonitor.jobLabel }} - namespaceSelector: - matchNames: - - default - selector: -{{ toYaml .Values.kubeApiServer.serviceMonitor.selector | indent 4 }} -{{- end}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/endpoints.yaml deleted file mode 100644 index 6a6afa6412..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/endpoints.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.endpoints .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Endpoints -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-controller-manager - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-controller-manager - k8s-app: kube-controller-manager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -subsets: - - addresses: - {{- range .Values.kubeControllerManager.endpoints }} - - ip: {{ . }} - {{- end }} - ports: - - name: {{ .Values.kubeControllerManager.serviceMonitor.port }} - {{- $kubeControllerManagerDefaultInsecurePort := 10252 }} - {{- $kubeControllerManagerDefaultSecurePort := 10257 }} - port: {{ include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.port) }} - protocol: TCP -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/service.yaml deleted file mode 100644 index 0a901c4acf..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/service.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.service.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-controller-manager - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-controller-manager - jobLabel: kube-controller-manager -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -spec: - clusterIP: None - {{- if .Values.kubeControllerManager.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.kubeControllerManager.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.kubeControllerManager.service.ipDualStack.ipFamilyPolicy }} - {{- end }} - ports: - - name: {{ .Values.kubeControllerManager.serviceMonitor.port }} - {{- $kubeControllerManagerDefaultInsecurePort := 10252 }} - {{- $kubeControllerManagerDefaultSecurePort := 10257 }} - port: {{ include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.port) }} - protocol: TCP - targetPort: {{ include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.targetPort) }} -{{- if .Values.kubeControllerManager.endpoints }}{{- else }} - selector: - {{- if .Values.kubeControllerManager.service.selector }} -{{ toYaml .Values.kubeControllerManager.service.selector | indent 4 }} - {{- else}} - component: kube-controller-manager - {{- end}} -{{- end }} - type: ClusterIP -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/servicemonitor.yaml deleted file mode 100644 index 7ed3baa65f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-controller-manager/servicemonitor.yaml +++ /dev/null @@ -1,69 +0,0 @@ -{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-controller-manager - {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - namespace: kube-system - {{- else }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-controller-manager - {{- with .Values.kubeControllerManager.serviceMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - jobLabel: {{ .Values.kubeControllerManager.serviceMonitor.jobLabel }} - {{- include "servicemonitor.scrapeLimits" .Values.kubeControllerManager.serviceMonitor | nindent 2 }} - selector: - {{- if .Values.kubeControllerManager.serviceMonitor.selector }} - {{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.selector | nindent 4) . }} - {{- else }} - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-controller-manager - release: {{ $.Release.Name | quote }} - {{- end }} - namespaceSelector: - matchNames: - - "kube-system" - endpoints: - - port: {{ .Values.kubeControllerManager.serviceMonitor.port }} - {{- if .Values.kubeControllerManager.serviceMonitor.interval }} - interval: {{ .Values.kubeControllerManager.serviceMonitor.interval }} - {{- end }} - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - {{- if .Values.kubeControllerManager.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubeControllerManager.serviceMonitor.proxyUrl}} - {{- end }} - {{- if eq (include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . false true .Values.kubeControllerManager.serviceMonitor.https )) "true" }} - scheme: https - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - {{- if eq (include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . nil true .Values.kubeControllerManager.serviceMonitor.insecureSkipVerify)) "true" }} - insecureSkipVerify: true - {{- end }} - {{- if .Values.kubeControllerManager.serviceMonitor.serverName }} - serverName: {{ .Values.kubeControllerManager.serviceMonitor.serverName }} - {{- end }} - {{- end }} - metricRelabelings: - {{- if.Values.kubeControllerManager.serviceMonitor.metricRelabelings }} - {{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.metricRelabelings | indent 4) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.kubeControllerManager.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.relabelings | indent 4) . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-dns/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-dns/service.yaml deleted file mode 100644 index 478f419400..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-dns/service.yaml +++ /dev/null @@ -1,32 +0,0 @@ -{{- if and .Values.kubeDns.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-dns - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-dns - jobLabel: kube-dns -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -spec: - clusterIP: None - {{- if .Values.kubeDns.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.kubeDns.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.kubeDns.service.ipDualStack.ipFamilyPolicy }} - {{- end }} - ports: - - name: http-metrics-dnsmasq - port: {{ .Values.kubeDns.service.dnsmasq.port }} - protocol: TCP - targetPort: {{ .Values.kubeDns.service.dnsmasq.targetPort }} - - name: http-metrics-skydns - port: {{ .Values.kubeDns.service.skydns.port }} - protocol: TCP - targetPort: {{ .Values.kubeDns.service.skydns.targetPort }} - selector: - {{- if .Values.kubeDns.service.selector }} -{{ toYaml .Values.kubeDns.service.selector | indent 4 }} - {{- else}} - k8s-app: kube-dns - {{- end}} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-dns/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-dns/servicemonitor.yaml deleted file mode 100644 index 9fa41b575f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-dns/servicemonitor.yaml +++ /dev/null @@ -1,71 +0,0 @@ -{{- if and .Values.kubeDns.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-dns - {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - namespace: kube-system - {{- else }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-dns - {{- with .Values.kubeDns.serviceMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - jobLabel: {{ .Values.kubeDns.serviceMonitor.jobLabel }} - {{- include "servicemonitor.scrapeLimits" .Values.kubeDns.serviceMonitor | nindent 2 }} - selector: - {{- if .Values.kubeDns.serviceMonitor.selector }} - {{ tpl (toYaml .Values.kubeDns.serviceMonitor.selector | nindent 4) . }} - {{- else }} - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-dns - release: {{ $.Release.Name | quote }} - {{- end }} - namespaceSelector: - matchNames: - - "kube-system" - endpoints: - - port: http-metrics-dnsmasq - {{- if .Values.kubeDns.serviceMonitor.interval }} - interval: {{ .Values.kubeDns.serviceMonitor.interval }} - {{- end }} - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - {{- if .Values.kubeDns.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubeDns.serviceMonitor.proxyUrl}} - {{- end }} - metricRelabelings: - {{- if .Values.kubeDns.serviceMonitor.dnsmasqMetricRelabelings }} - {{ tpl (toYaml .Values.kubeDns.serviceMonitor.dnsmasqMetricRelabelings | indent 4) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.kubeDns.serviceMonitor.dnsmasqRelabelings }} - relabelings: -{{ toYaml .Values.kubeDns.serviceMonitor.dnsmasqRelabelings | indent 4 }} -{{- end }} - - port: http-metrics-skydns - {{- if .Values.kubeDns.serviceMonitor.interval }} - interval: {{ .Values.kubeDns.serviceMonitor.interval }} - {{- end }} - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token -{{- if .Values.kubeDns.serviceMonitor.metricRelabelings }} - metricRelabelings: -{{ tpl (toYaml .Values.kubeDns.serviceMonitor.metricRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubeDns.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.kubeDns.serviceMonitor.relabelings | indent 4) . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/endpoints.yaml deleted file mode 100644 index e366447577..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/endpoints.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.endpoints .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Endpoints -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-etcd - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-etcd - k8s-app: etcd-server -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -subsets: - - addresses: - {{- range .Values.kubeEtcd.endpoints }} - - ip: {{ . }} - {{- end }} - ports: - - name: {{ .Values.kubeEtcd.serviceMonitor.port }} - port: {{ .Values.kubeEtcd.service.port }} - protocol: TCP -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/service.yaml deleted file mode 100644 index a62059aa4e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/service.yaml +++ /dev/null @@ -1,31 +0,0 @@ -{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.service.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-etcd - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-etcd - jobLabel: kube-etcd -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -spec: - clusterIP: None - {{- if .Values.kubeEtcd.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.kubeEtcd.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.kubeEtcd.service.ipDualStack.ipFamilyPolicy }} - {{- end }} - ports: - - name: {{ .Values.kubeEtcd.serviceMonitor.port }} - port: {{ .Values.kubeEtcd.service.port }} - protocol: TCP - targetPort: {{ .Values.kubeEtcd.service.targetPort }} -{{- if .Values.kubeEtcd.endpoints }}{{- else }} - selector: - {{- if .Values.kubeEtcd.service.selector }} -{{ toYaml .Values.kubeEtcd.service.selector | indent 4 }} - {{- else}} - component: etcd - {{- end}} -{{- end }} - type: ClusterIP -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/servicemonitor.yaml deleted file mode 100644 index 26fdbdbed3..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-etcd/servicemonitor.yaml +++ /dev/null @@ -1,75 +0,0 @@ -{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-etcd - {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - namespace: kube-system - {{- else }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-etcd - {{- with .Values.kubeEtcd.serviceMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - jobLabel: {{ .Values.kubeEtcd.serviceMonitor.jobLabel }} - {{- include "servicemonitor.scrapeLimits" .Values.kubeEtcd.serviceMonitor | nindent 4 }} - selector: - {{- if .Values.kubeEtcd.serviceMonitor.selector }} - {{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.selector | nindent 4) . }} - {{- else }} - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-etcd - release: {{ $.Release.Name | quote }} - {{- end }} - namespaceSelector: - matchNames: - - "kube-system" - endpoints: - - port: {{ .Values.kubeEtcd.serviceMonitor.port }} - {{- if .Values.kubeEtcd.serviceMonitor.interval }} - interval: {{ .Values.kubeEtcd.serviceMonitor.interval }} - {{- end }} - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - {{- if .Values.kubeEtcd.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubeEtcd.serviceMonitor.proxyUrl}} - {{- end }} - {{- if eq .Values.kubeEtcd.serviceMonitor.scheme "https" }} - scheme: https - tlsConfig: - {{- if .Values.kubeEtcd.serviceMonitor.serverName }} - serverName: {{ .Values.kubeEtcd.serviceMonitor.serverName }} - {{- end }} - {{- if .Values.kubeEtcd.serviceMonitor.caFile }} - caFile: {{ .Values.kubeEtcd.serviceMonitor.caFile }} - {{- end }} - {{- if .Values.kubeEtcd.serviceMonitor.certFile }} - certFile: {{ .Values.kubeEtcd.serviceMonitor.certFile }} - {{- end }} - {{- if .Values.kubeEtcd.serviceMonitor.keyFile }} - keyFile: {{ .Values.kubeEtcd.serviceMonitor.keyFile }} - {{- end}} - insecureSkipVerify: {{ .Values.kubeEtcd.serviceMonitor.insecureSkipVerify }} - {{- end }} - metricRelabelings: - {{- if .Values.kubeEtcd.serviceMonitor.metricRelabelings }} - {{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.metricRelabelings | indent 4) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.kubeEtcd.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.relabelings | indent 4) . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/endpoints.yaml deleted file mode 100644 index 8613e62425..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/endpoints.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.endpoints .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Endpoints -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-proxy - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-proxy - k8s-app: kube-proxy -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -subsets: - - addresses: - {{- range .Values.kubeProxy.endpoints }} - - ip: {{ . }} - {{- end }} - ports: - - name: {{ .Values.kubeProxy.serviceMonitor.port }} - port: {{ .Values.kubeProxy.service.port }} - protocol: TCP -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/service.yaml deleted file mode 100644 index 672f5492b8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/service.yaml +++ /dev/null @@ -1,31 +0,0 @@ -{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.service.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-proxy - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-proxy - jobLabel: kube-proxy -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -spec: - clusterIP: None - {{- if .Values.kubeProxy.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.kubeProxy.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.kubeProxy.service.ipDualStack.ipFamilyPolicy }} - {{- end }} - ports: - - name: {{ .Values.kubeProxy.serviceMonitor.port }} - port: {{ .Values.kubeProxy.service.port }} - protocol: TCP - targetPort: {{ .Values.kubeProxy.service.targetPort }} -{{- if .Values.kubeProxy.endpoints }}{{- else }} - selector: - {{- if .Values.kubeProxy.service.selector }} -{{ toYaml .Values.kubeProxy.service.selector | indent 4 }} - {{- else}} - k8s-app: kube-proxy - {{- end}} -{{- end }} - type: ClusterIP -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/servicemonitor.yaml deleted file mode 100644 index 24b0ab2001..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-proxy/servicemonitor.yaml +++ /dev/null @@ -1,63 +0,0 @@ -{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-proxy - {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - namespace: kube-system - {{- else }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-proxy - {{- with .Values.kubeProxy.serviceMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - jobLabel: {{ .Values.kubeProxy.serviceMonitor.jobLabel }} - {{- include "servicemonitor.scrapeLimits" .Values.kubeProxy.serviceMonitor | nindent 2 }} - selector: - {{- if .Values.kubeProxy.serviceMonitor.selector }} - {{ tpl (toYaml .Values.kubeProxy.serviceMonitor.selector | nindent 4) . }} - {{- else }} - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-proxy - release: {{ $.Release.Name | quote }} - {{- end }} - namespaceSelector: - matchNames: - - "kube-system" - endpoints: - - port: {{ .Values.kubeProxy.serviceMonitor.port }} - {{- if .Values.kubeProxy.serviceMonitor.interval }} - interval: {{ .Values.kubeProxy.serviceMonitor.interval }} - {{- end }} - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - {{- if .Values.kubeProxy.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubeProxy.serviceMonitor.proxyUrl}} - {{- end }} - {{- if .Values.kubeProxy.serviceMonitor.https }} - scheme: https - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - {{- end}} - metricRelabelings: - {{- if .Values.kubeProxy.serviceMonitor.metricRelabelings }} - {{ tpl (toYaml .Values.kubeProxy.serviceMonitor.metricRelabelings | indent 4) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.kubeProxy.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.kubeProxy.serviceMonitor.relabelings | indent 4) . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/endpoints.yaml deleted file mode 100644 index 6236b42f10..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/endpoints.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.endpoints .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Endpoints -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-scheduler - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-scheduler - k8s-app: kube-scheduler -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -subsets: - - addresses: - {{- range .Values.kubeScheduler.endpoints }} - - ip: {{ . }} - {{- end }} - ports: - - name: {{ .Values.kubeScheduler.serviceMonitor.port }} - {{- $kubeSchedulerDefaultInsecurePort := 10251 }} - {{- $kubeSchedulerDefaultSecurePort := 10259 }} - port: {{ include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.port) }} - protocol: TCP -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/service.yaml deleted file mode 100644 index 8663d79f0d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/service.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.service.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-scheduler - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-scheduler - jobLabel: kube-scheduler -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: kube-system -spec: - clusterIP: None - {{- if .Values.kubeScheduler.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.kubeScheduler.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.kubeScheduler.service.ipDualStack.ipFamilyPolicy }} - {{- end }} - ports: - - name: {{ .Values.kubeScheduler.serviceMonitor.port }} - {{- $kubeSchedulerDefaultInsecurePort := 10251 }} - {{- $kubeSchedulerDefaultSecurePort := 10259 }} - port: {{ include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.port) }} - protocol: TCP - targetPort: {{ include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.targetPort) }} -{{- if .Values.kubeScheduler.endpoints }}{{- else }} - selector: - {{- if .Values.kubeScheduler.service.selector }} -{{ toYaml .Values.kubeScheduler.service.selector | indent 4 }} - {{- else}} - component: kube-scheduler - {{- end}} -{{- end }} - type: ClusterIP -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/servicemonitor.yaml deleted file mode 100644 index b17c4f1d47..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-scheduler/servicemonitor.yaml +++ /dev/null @@ -1,69 +0,0 @@ -{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kube-scheduler - {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - namespace: kube-system - {{- else }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-scheduler - {{- with .Values.kubeScheduler.serviceMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - jobLabel: {{ .Values.kubeScheduler.serviceMonitor.jobLabel }} - {{- include "servicemonitor.scrapeLimits" .Values.kubeScheduler.serviceMonitor | nindent 2 }} - selector: - {{- if .Values.kubeScheduler.serviceMonitor.selector }} - {{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.selector | nindent 4) . }} - {{- else }} - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-kube-scheduler - release: {{ $.Release.Name | quote }} - {{- end }} - namespaceSelector: - matchNames: - - "kube-system" - endpoints: - - port: {{ .Values.kubeScheduler.serviceMonitor.port }} - {{- if .Values.kubeScheduler.serviceMonitor.interval }} - interval: {{ .Values.kubeScheduler.serviceMonitor.interval }} - {{- end }} - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - {{- if .Values.kubeScheduler.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubeScheduler.serviceMonitor.proxyUrl}} - {{- end }} - {{- if eq (include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . false true .Values.kubeScheduler.serviceMonitor.https )) "true" }} - scheme: https - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - {{- if eq (include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . nil true .Values.kubeScheduler.serviceMonitor.insecureSkipVerify)) "true" }} - insecureSkipVerify: true - {{- end }} - {{- if .Values.kubeScheduler.serviceMonitor.serverName }} - serverName: {{ .Values.kubeScheduler.serviceMonitor.serverName }} - {{- end}} - {{- end}} - metricRelabelings: - {{- if .Values.kubeScheduler.serviceMonitor.metricRelabelings }} - {{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.metricRelabelings | indent 4) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.kubeScheduler.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.relabelings | indent 4) . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-state-metrics/validate.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-state-metrics/validate.yaml deleted file mode 100644 index 9211b3d771..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kube-state-metrics/validate.yaml +++ /dev/null @@ -1,7 +0,0 @@ -{{- if .Values.kubeStateMetrics.enabled }} -{{- if not (kindIs "invalid" .Values.kubeStateMetrics.serviceMonitor) }} -{{- if .Values.kubeStateMetrics.serviceMonitor.namespaceOverride }} -{{- fail "kubeStateMetrics.serviceMonitor.namespaceOverride was removed. Please use kube-state-metrics.namespaceOverride instead." }} -{{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kubelet/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kubelet/servicemonitor.yaml deleted file mode 100644 index f570fbfdbc..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/kubelet/servicemonitor.yaml +++ /dev/null @@ -1,246 +0,0 @@ -{{- if (and (not .Values.kubelet.enabled) .Values.hardenedKubelet.enabled) }} -{{ required "Cannot set .Values.hardenedKubelet.enabled=true when .Values.kubelet.enabled=false" "" }} -{{- end }} -{{- if (and .Values.kubelet.enabled .Values.kubernetesServiceMonitors.enabled (not .Values.hardenedKubelet.enabled) (not .Values.k3sServer.enabled)) }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-kubelet - {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - namespace: {{ .Values.kubelet.namespace }} - {{- else }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-kubelet - {{- with .Values.kubelet.serviceMonitor.additionalLabels }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{- include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - {{- include "servicemonitor.scrapeLimits" .Values.kubelet.serviceMonitor | nindent 2 }} - {{- with .Values.kubelet.serviceMonitor.attachMetadata }} - attachMetadata: - {{- toYaml . | nindent 4 }} - {{- end }} - endpoints: - {{- if .Values.kubelet.serviceMonitor.https }} - - port: https-metrics - scheme: https - {{- if .Values.kubelet.serviceMonitor.interval }} - interval: {{ .Values.kubelet.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} - {{- end }} - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - insecureSkipVerify: true - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} - honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} - metricRelabelings: - {{- if .Values.kubelet.serviceMonitor.metricRelabelings }} - {{- tpl (toYaml .Values.kubelet.serviceMonitor.metricRelabelings | nindent 6) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.kubelet.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.relabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.cAdvisor }} - - port: https-metrics - scheme: https - path: /metrics/cadvisor - {{- if .Values.kubelet.serviceMonitor.interval }} - interval: {{ .Values.kubelet.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} - {{- end }} - honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} - honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - insecureSkipVerify: true - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token -{{- if .Values.kubelet.serviceMonitor.cAdvisorMetricRelabelings }} - metricRelabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.cAdvisorMetricRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.cAdvisorRelabelings }} - relabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.cAdvisorRelabelings | indent 4) . }} -{{- end }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.probes }} - - port: https-metrics - scheme: https - path: /metrics/probes - {{- if .Values.kubelet.serviceMonitor.interval }} - interval: {{ .Values.kubelet.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} - {{- end }} - honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} - honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - insecureSkipVerify: true - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token -{{- if .Values.kubelet.serviceMonitor.probesMetricRelabelings }} - metricRelabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.probesMetricRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.probesRelabelings }} - relabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.probesRelabelings | indent 4) . }} -{{- end }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.resource }} - - port: https-metrics - scheme: https - path: {{ include "kubelet.serviceMonitor.resourcePath" . }} - {{- if .Values.kubelet.serviceMonitor.interval }} - interval: {{ .Values.kubelet.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} - {{- end }} - honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} - honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - insecureSkipVerify: true - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token -{{- if .Values.kubelet.serviceMonitor.resourceMetricRelabelings }} - metricRelabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.resourceMetricRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.resourceRelabelings }} - relabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.resourceRelabelings | indent 4) . }} -{{- end }} -{{- end }} - {{- else }} - - port: http-metrics - {{- if .Values.kubelet.serviceMonitor.interval }} - interval: {{ .Values.kubelet.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} - {{- end }} - honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} - honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} -{{- if .Values.kubelet.serviceMonitor.metricRelabelings }} - metricRelabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.metricRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.relabelings }} - relabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.relabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.cAdvisor }} - - port: http-metrics - path: /metrics/cadvisor - {{- if .Values.kubelet.serviceMonitor.interval }} - interval: {{ .Values.kubelet.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} - {{- end }} - honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} - honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} -{{- if .Values.kubelet.serviceMonitor.cAdvisorMetricRelabelings }} - metricRelabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.cAdvisorMetricRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.cAdvisorRelabelings }} - relabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.cAdvisorRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.probes }} - - port: http-metrics - path: /metrics/probes - {{- if .Values.kubelet.serviceMonitor.interval }} - interval: {{ .Values.kubelet.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} - {{- end }} - honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} - honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} -{{- if .Values.kubelet.serviceMonitor.probesMetricRelabelings }} - metricRelabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.probesMetricRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.probesRelabelings }} - relabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.probesRelabelings | indent 4) . }} -{{- end }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.resource }} - - port: http-metrics - path: {{ include "kubelet.serviceMonitor.resourcePath" . }} - {{- if .Values.kubelet.serviceMonitor.interval }} - interval: {{ .Values.kubelet.serviceMonitor.interval }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} - {{- end }} - {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} - scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} - {{- end }} - honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} - honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} -{{- if .Values.kubelet.serviceMonitor.resourceMetricRelabelings }} - metricRelabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.resourceMetricRelabelings | indent 4) . }} -{{- end }} -{{- if .Values.kubelet.serviceMonitor.resourceRelabelings }} - relabelings: -{{ tpl (toYaml .Values.kubelet.serviceMonitor.resourceRelabelings | indent 4) . }} -{{- end }} -{{- end }} -{{- end }} - {{- end }} - jobLabel: k8s-app - namespaceSelector: - matchNames: - - {{ .Values.kubelet.namespace }} - selector: - matchLabels: - app.kubernetes.io/name: kubelet - k8s-app: kubelet -{{- end}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/node-exporter/validate.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/node-exporter/validate.yaml deleted file mode 100644 index bdc73d6165..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/exporters/node-exporter/validate.yaml +++ /dev/null @@ -1,3 +0,0 @@ -{{- if (and (not .Values.nodeExporter.enabled) .Values.hardenedNodeExporter.enabled) }} -{{ required "Cannot set .Values.hardenedNodeExporter.enabled=true when .Values.nodeExporter.enabled=false" "" }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/extra-objects.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/extra-objects.yaml deleted file mode 100644 index 567f7bf329..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/extra-objects.yaml +++ /dev/null @@ -1,4 +0,0 @@ -{{ range .Values.extraManifests }} ---- -{{ tpl (toYaml .) $ }} -{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/configmap-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/configmap-dashboards.yaml deleted file mode 100644 index e719009ffe..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/configmap-dashboards.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if or (and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled) .Values.grafana.forceDeployDashboards }} -{{- $files := .Files.Glob "dashboards-1.14/*.json" }} -{{- if $files }} -apiVersion: v1 -kind: ConfigMapList -items: -{{- range $path, $fileContents := $files }} -{{- $dashboardName := regexReplaceAll "(^.*/)(.*)\\.json$" $path "${2}" }} -- apiVersion: v1 - kind: ConfigMap - metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) $dashboardName | trunc 63 | trimSuffix "-" }} - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 6 }} - data: - {{ $dashboardName }}.json: {{ $.Files.Get $path | toJson }} -{{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/configmaps-datasources.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/configmaps-datasources.yaml deleted file mode 100644 index 135bad440d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/configmaps-datasources.yaml +++ /dev/null @@ -1,81 +0,0 @@ -{{- if or (and .Values.grafana.enabled .Values.grafana.sidecar.datasources.enabled) .Values.grafana.forceDeployDatasources }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-grafana-datasource - namespace: {{ default .Values.grafana.sidecar.datasources.searchNamespace (include "kube-prometheus-stack.namespace" .) }} -{{- if .Values.grafana.sidecar.datasources.annotations }} - annotations: - {{- toYaml .Values.grafana.sidecar.datasources.annotations | nindent 4 }} -{{- end }} - labels: - {{ $.Values.grafana.sidecar.datasources.label }}: {{ $.Values.grafana.sidecar.datasources.labelValue | quote }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - datasource.yaml: |- - apiVersion: 1 -{{- if .Values.grafana.deleteDatasources }} - deleteDatasources: -{{ tpl (toYaml .Values.grafana.deleteDatasources | indent 6) . }} -{{- end }} - datasources: -{{- $scrapeInterval := .Values.grafana.sidecar.datasources.defaultDatasourceScrapeInterval | default .Values.prometheus.prometheusSpec.scrapeInterval | default "30s" }} -{{- if .Values.grafana.sidecar.datasources.defaultDatasourceEnabled }} - - name: "{{ .Values.grafana.sidecar.datasources.name }}" - type: prometheus - uid: {{ .Values.grafana.sidecar.datasources.uid }} - {{- if .Values.grafana.sidecar.datasources.url }} - url: {{ .Values.grafana.sidecar.datasources.url }} - {{- else }} - url: http://{{ template "kube-prometheus-stack.fullname" . }}-prometheus.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.prometheus.service.port }}/{{ trimPrefix "/" .Values.prometheus.prometheusSpec.routePrefix }} - {{- end }} - access: proxy - isDefault: {{ .Values.grafana.sidecar.datasources.isDefaultDatasource }} - jsonData: - httpMethod: {{ .Values.grafana.sidecar.datasources.httpMethod }} - timeInterval: {{ $scrapeInterval }} - {{- if .Values.grafana.sidecar.datasources.timeout }} - timeout: {{ .Values.grafana.sidecar.datasources.timeout }} - {{- end }} -{{- if .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations }} - exemplarTraceIdDestinations: - - datasourceUid: {{ .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.datasourceUid }} - name: {{ .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.traceIdLabelName }} -{{- end }} -{{- if .Values.grafana.sidecar.datasources.createPrometheusReplicasDatasources }} -{{- range until (int .Values.prometheus.prometheusSpec.replicas) }} - - name: "{{ $.Values.grafana.sidecar.datasources.name }}-{{ . }}" - type: prometheus - uid: {{ $.Values.grafana.sidecar.datasources.uid }}-replica-{{ . }} - url: http://prometheus-{{ template "kube-prometheus-stack.prometheus.crname" $ }}-{{ . }}.prometheus-operated:9090/{{ trimPrefix "/" $.Values.prometheus.prometheusSpec.routePrefix }} - access: proxy - isDefault: false - jsonData: - timeInterval: {{ $scrapeInterval }} -{{- if $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations }} - exemplarTraceIdDestinations: - - datasourceUid: {{ $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.datasourceUid }} - name: {{ $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.traceIdLabelName }} -{{- end }} -{{- end }} -{{- end }} -{{- if .Values.grafana.sidecar.datasources.alertmanager.enabled }} - - name: "{{ .Values.grafana.sidecar.datasources.alertmanager.name }}" - type: alertmanager - uid: {{ .Values.grafana.sidecar.datasources.alertmanager.uid }} - {{- if .Values.grafana.sidecar.datasources.alertmanager.url }} - url: {{ .Values.grafana.sidecar.datasources.alertmanager.url }} - {{- else }} - url: http://{{ template "kube-prometheus-stack.fullname" . }}-alertmanager.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.alertmanager.service.port }}/{{ trimPrefix "/" .Values.alertmanager.alertmanagerSpec.routePrefix }} - {{- end }} - access: proxy - jsonData: - handleGrafanaManagedAlerts: {{ .Values.grafana.sidecar.datasources.alertmanager.handleGrafanaManagedAlerts }} - implementation: {{ .Values.grafana.sidecar.datasources.alertmanager.implementation }} -{{- end }} -{{- end }} -{{- if .Values.grafana.additionalDataSources }} -{{ tpl (toYaml .Values.grafana.additionalDataSources | indent 4) . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/alertmanager-overview.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/alertmanager-overview.yaml deleted file mode 100644 index 216467bdf7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/alertmanager-overview.yaml +++ /dev/null @@ -1,616 +0,0 @@ -{{- /* -Generated from 'alertmanager-overview' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -{{- if and .Values.alertmanager.enabled .Values.alertmanager.serviceMonitor.selfMonitor }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "alertmanager-overview" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - alertmanager-overview.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 1, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "30s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "current set of alerts stored in the Alertmanager", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 2, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(alertmanager_alerts{namespace=~\"$namespace\",service=~\"$service\"}) by (namespace,service,instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Alerts", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "none", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "none", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "rate of successful and invalid alerts received by the Alertmanager", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(alertmanager_alerts_received_total{namespace=~\"$namespace\",service=~\"$service\"}[$__rate_interval])) by (namespace,service,instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Received", - "refId": "A" - }, - { - "expr": "sum(rate(alertmanager_alerts_invalid_total{namespace=~\"$namespace\",service=~\"$service\"}[$__rate_interval])) by (namespace,service,instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Invalid", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Alerts receive rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Alerts", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "rate of successful and invalid notifications sent by the Alertmanager", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": "integration", - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(alertmanager_notifications_total{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (integration,namespace,service,instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Total", - "refId": "A" - }, - { - "expr": "sum(rate(alertmanager_notifications_failed_total{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (integration,namespace,service,instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Failed", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "$integration: Notifications Send Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "latency of notifications sent by the Alertmanager", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 5, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": "integration", - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99,\n sum(rate(alertmanager_notification_latency_seconds_bucket{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (le,namespace,service,instance)\n) \n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} 99th Percentile", - "refId": "A" - }, - { - "expr": "histogram_quantile(0.50,\n sum(rate(alertmanager_notification_latency_seconds_bucket{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (le,namespace,service,instance)\n) \n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Median", - "refId": "B" - }, - { - "expr": "sum(rate(alertmanager_notification_latency_seconds_sum{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (namespace,service,instance)\n/\nsum(rate(alertmanager_notification_latency_seconds_count{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (namespace,service,instance)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Average", - "refId": "C" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "$integration: Notification Duration", - "tooltip": { - "shared": true, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Notifications", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "alertmanager-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": "namespace", - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(alertmanager_alerts, namespace)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": "service", - "multi": false, - "name": "service", - "options": [ - - ], - "query": "label_values(alertmanager_alerts, service)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "all", - "value": "$__all" - }, - "datasource": "$datasource", - "hide": 2, - "includeAll": true, - "label": null, - "multi": false, - "name": "integration", - "options": [ - - ], - "query": "label_values(alertmanager_notifications_total{integration=~\".*\"}, integration)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Alertmanager / Overview", - "uid": "alertmanager-overview", - "version": 0 - } -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/apiserver.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/apiserver.yaml deleted file mode 100644 index c05d6ceebb..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/apiserver.yaml +++ /dev/null @@ -1,1772 +0,0 @@ -{{- /* -Generated from 'apiserver' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.kubeApiServer.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "apiserver" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - apiserver.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "panels": [ - { - "content": "The SLO (service level objective) and other metrics displayed on this dashboard are for informational purposes only.", - "datasource": null, - "description": "The SLO (service level objective) and other metrics displayed on this dashboard are for informational purposes only.", - "gridPos": { - "h": 2, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 2, - "mode": "markdown", - "span": 12, - "title": "Notice", - "type": "text" - } - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "decimals": 3, - "description": "How many percent of requests (both read and write) in 30 days have been answered successfully and fast enough?", - "format": "percentunit", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - - }, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "rightSide": true - }, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 4, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "apiserver_request:availability30d{verb=\"all\", cluster=\"$cluster\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "title": "Availability (30d) > 99.000%", - "tooltip": { - "shared": false - }, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": 3, - "description": "How much error budget is left looking at our 0.990% availability guarantees?", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 8, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "100 * (apiserver_request:availability30d{verb=\"all\", cluster=\"$cluster\"} - 0.990000)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "errorbudget", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "ErrorBudget (30d) > 99.000%", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "decimals": 3, - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "decimals": 3, - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "decimals": 3, - "description": "How many percent of read requests (LIST,GET) in 30 days have been answered successfully and fast enough?", - "format": "percentunit", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - - }, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "rightSide": true - }, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 3, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "apiserver_request:availability30d{verb=\"read\", cluster=\"$cluster\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "title": "Read Availability (30d)", - "tooltip": { - "shared": false - }, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "How many read requests (LIST,GET) per second do the apiservers get by code?", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - { - "alias": "/2../i", - "color": "#56A64B" - }, - { - "alias": "/3../i", - "color": "#F2CC0C" - }, - { - "alias": "/4../i", - "color": "#3274D9" - }, - { - "alias": "/5../i", - "color": "#E02F44" - } - ], - "spaceLength": 10, - "span": 3, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (code) (code_resource:apiserver_request_total:rate5m{verb=\"read\", cluster=\"$cluster\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}} code {{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Read SLI - Requests", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "How many percent of read requests (LIST,GET) per second are returned with errors (5xx)?", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"read\",code=~\"5..\", cluster=\"$cluster\"}) / sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"read\", cluster=\"$cluster\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}} resource {{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Read SLI - Errors", - "tooltip": { - "shared": false, - "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": null, - "min": 0, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "How many seconds is the 99th percentile for reading (LIST|GET) a given resource?", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "cluster_quantile:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds:histogram_quantile{verb=\"read\", cluster=\"$cluster\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}} resource {{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Read SLI - Duration", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "decimals": 3, - "description": "How many percent of write requests (POST|PUT|PATCH|DELETE) in 30 days have been answered successfully and fast enough?", - "format": "percentunit", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - - }, - "id": 9, - "interval": "1m", - "legend": { - "alignAsTable": true, - "rightSide": true - }, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 3, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "apiserver_request:availability30d{verb=\"write\", cluster=\"$cluster\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "title": "Write Availability (30d)", - "tooltip": { - "shared": false - }, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "How many write requests (POST|PUT|PATCH|DELETE) per second do the apiservers get by code?", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - { - "alias": "/2../i", - "color": "#56A64B" - }, - { - "alias": "/3../i", - "color": "#F2CC0C" - }, - { - "alias": "/4../i", - "color": "#3274D9" - }, - { - "alias": "/5../i", - "color": "#E02F44" - } - ], - "spaceLength": 10, - "span": 3, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (code) (code_resource:apiserver_request_total:rate5m{verb=\"write\", cluster=\"$cluster\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}} code {{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Write SLI - Requests", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "How many percent of write requests (POST|PUT|PATCH|DELETE) per second are returned with errors (5xx)?", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 11, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"write\",code=~\"5..\", cluster=\"$cluster\"}) / sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"write\", cluster=\"$cluster\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}} resource {{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Write SLI - Errors", - "tooltip": { - "shared": false, - "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": null, - "min": 0, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "How many seconds is the 99th percentile for writing (POST|PUT|PATCH|DELETE) a given resource?", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 12, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "cluster_quantile:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds:histogram_quantile{verb=\"write\", cluster=\"$cluster\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}} resource {{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Write SLI - Duration", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 13, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(workqueue_adds_total{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Work Queue Add Rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 14, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(workqueue_depth{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Work Queue Depth", - "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": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 15, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Work Queue Latency", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 16, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "process_resident_memory_bytes{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory", - "tooltip": { - "shared": false, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 17, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(process_cpu_seconds_total{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU usage", - "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": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 18, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "go_goroutines{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Goroutines", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": "cluster", - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"apiserver\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(up{job=\"apiserver\", cluster=\"$cluster\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / API server", - "uid": "09ec8aa1e996d6ffcd6817bbaff4db1b", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/cluster-total.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/cluster-total.yaml deleted file mode 100644 index cf8e00540c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/cluster-total.yaml +++ /dev/null @@ -1,1882 +0,0 @@ -{{- /* -Generated from 'cluster-total' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "cluster-total" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - cluster-total.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "panels": [ - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 2, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Current Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 1 - }, - "id": 3, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Received", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 1 - }, - "id": 4, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Transmitted", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "columns": [ - { - "text": "Time", - "value": "Time" - }, - { - "text": "Value #A", - "value": "Value #A" - }, - { - "text": "Value #B", - "value": "Value #B" - }, - { - "text": "Value #C", - "value": "Value #C" - }, - { - "text": "Value #D", - "value": "Value #D" - }, - { - "text": "Value #E", - "value": "Value #E" - }, - { - "text": "Value #F", - "value": "Value #F" - }, - { - "text": "Value #G", - "value": "Value #G" - }, - { - "text": "Value #H", - "value": "Value #H" - }, - { - "text": "namespace", - "value": "namespace" - } - ], - "datasource": "$datasource", - "fill": 1, - "fontSize": "90%", - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 10 - }, - "id": 5, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null as zero", - "renderer": "flot", - "scroll": true, - "showHeader": true, - "sort": { - "col": 0, - "desc": false - }, - "spaceLength": 10, - "span": 24, - "styles": [ - { - "alias": "Time", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Time", - "thresholds": [ - - ], - "type": "hidden", - "unit": "short" - }, - { - "alias": "Current Bandwidth Received", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Current Bandwidth Transmitted", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Average Bandwidth Received", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Average Bandwidth Transmitted", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Rate of Received Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Received Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #G", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #H", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Namespace", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTooltip": "Drill down", - "linkUrl": "d/8b7a8b326d7a6f1f04244066368c67af/kubernetes-networking-namespace-pods?orgId=1&refresh=30s&var-namespace=$__cell", - "pattern": "namespace", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "G", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "H", - "step": 10 - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Status", - "type": "table" - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 10 - }, - "id": 6, - "panels": [ - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 11 - }, - "id": 7, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Rate of Bytes Received", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 11 - }, - "id": 8, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Rate of Bytes Transmitted", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Average Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 11 - }, - "id": 9, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth History", - "titleSize": "h6", - "type": "row" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 12 - }, - "id": 10, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 21 - }, - "id": 11, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 30 - }, - "id": 12, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 31 - }, - "id": 13, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 40 - }, - "id": 14, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Packets", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 31 - }, - "id": 15, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 50 - }, - "id": 16, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 59 - }, - "id": 17, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 59 - }, - "id": 18, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [ - { - "targetBlank": true, - "title": "What is TCP Retransmit?", - "url": "https://accedian.com/enterprises/blog/network-packet-loss-retransmissions-and-duplicate-acknowledgements/" - } - ], - "minSpan": 24, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(rate(node_netstat_Tcp_RetransSegs{cluster=\"$cluster\"}[$interval:$resolution]) / rate(node_netstat_Tcp_OutSegs{cluster=\"$cluster\"}[$interval:$resolution])) by (instance))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of TCP Retransmits out of all sent segments", - "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": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 59 - }, - "id": 19, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [ - { - "targetBlank": true, - "title": "Why monitor SYN retransmits?", - "url": "https://github.com/prometheus/node_exporter/issues/1023#issuecomment-408128365" - } - ], - "minSpan": 24, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(rate(node_netstat_TcpExt_TCPSynRetrans{cluster=\"$cluster\"}[$interval:$resolution]) / rate(node_netstat_Tcp_RetransSegs{cluster=\"$cluster\"}[$interval:$resolution])) by (instance))", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of TCP SYN Retransmits out of all retransmits", - "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": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Errors", - "titleSize": "h6", - "type": "row" - } - ], - "refresh": "10s", - "rows": [ - - ], - "schemaVersion": 18, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "resolution", - "options": [ - { - "selected": false, - "text": "30s", - "value": "30s" - }, - { - "selected": true, - "text": "5m", - "value": "5m" - }, - { - "selected": false, - "text": "1h", - "value": "1h" - } - ], - "query": "30s,5m,1h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 2, - "includeAll": false, - "label": null, - "multi": false, - "name": "interval", - "options": [ - { - "selected": true, - "text": "4h", - "value": "4h" - } - ], - "query": "4h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "useTags": false - }, - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 0, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Networking / Cluster", - "uid": "ff635a025bcfea7bc3dd4f508990a3e9", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/controller-manager.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/controller-manager.yaml deleted file mode 100644 index 507d47555d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/controller-manager.yaml +++ /dev/null @@ -1,1196 +0,0 @@ -{{- /* -Generated from 'controller-manager' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -{{- if (include "exporter.kubeControllerManager.enabled" .)}} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "controller-manager" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - controller-manager.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - - }, - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "rightSide": true - }, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 2, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - {{- if .Values.k3sServer.enabled }} - "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", metrics_path=\"/metrics\"})", - {{- else }} - "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\"})", - {{- end }} - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "title": "Up", - "tooltip": { - "shared": false - }, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "min" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(workqueue_adds_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Work Queue Add Rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(workqueue_depth{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Work Queue Depth", - "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": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Work Queue Latency", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(rest_client_requests_total{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "2xx", - "refId": "A" - }, - { - "expr": "sum(rate(rest_client_requests_total{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "3xx", - "refId": "B" - }, - { - "expr": "sum(rate(rest_client_requests_total{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "4xx", - "refId": "C" - }, - { - "expr": "sum(rate(rest_client_requests_total{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "5xx", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Kube API Request Rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 8, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\", verb=\"POST\"}[$__rate_interval])) by (verb, url, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Post Request Latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, url, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Get Request Latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 9, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory", - "tooltip": { - "shared": false, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU usage", - "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": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 11, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "go_goroutines{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Goroutines", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": "cluster", - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Controller Manager", - "uid": "72e0e05bef5099e5f049b05fdc429ed4", - "version": 0 - } -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/etcd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/etcd.yaml deleted file mode 100644 index 0eeedc6299..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/etcd.yaml +++ /dev/null @@ -1,1229 +0,0 @@ -{{- /* -Generated from 'etcd' from https://github.com/etcd-io/etcd.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -{{- if (include "exporter.kubeEtcd.enabled" .)}} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "etcd" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - etcd.json: |- - { - "annotations": { - "list": [] - }, - "description": "etcd sample Grafana dashboard with Prometheus", - "editable": true, - "gnetId": null, - "hideControls": false, - "links": [], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "editable": true, - "height": "250px", - "panels": [ - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$datasource", - "editable": true, - "error": false, - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "id": 28, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 3, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "targets": [ - { - "expr": "sum(etcd_server_has_leader{job=\"$cluster\"})", - "intervalFactor": 2, - "legendFormat": "", - "metric": "etcd_server_has_leader", - "refId": "A", - "step": 20 - } - ], - "thresholds": "", - "title": "Up", - "type": "singlestat", - "valueFontSize": "200%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fill": 0, - "id": 23, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 5, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(grpc_server_started_total{job=\"$cluster\",grpc_type=\"unary\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "RPC Rate", - "metric": "grpc_server_started_total", - "refId": "A", - "step": 2 - }, - { - "expr": "sum(rate(grpc_server_handled_total{job=\"$cluster\",grpc_type=\"unary\",grpc_code=~\"Unknown|FailedPrecondition|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "RPC Failed Rate", - "metric": "grpc_server_handled_total", - "refId": "B", - "step": 2 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "RPC Rate", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fill": 0, - "id": 41, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 4, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(grpc_server_started_total{job=\"$cluster\",grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"}) - sum(grpc_server_handled_total{job=\"$cluster\",grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"})", - "intervalFactor": 2, - "legendFormat": "Watch Streams", - "metric": "grpc_server_handled_total", - "refId": "A", - "step": 4 - }, - { - "expr": "sum(grpc_server_started_total{job=\"$cluster\",grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"}) - sum(grpc_server_handled_total{job=\"$cluster\",grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"})", - "intervalFactor": 2, - "legendFormat": "Lease Streams", - "metric": "grpc_server_handled_total", - "refId": "B", - "step": 4 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Active Streams", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "showTitle": false, - "title": "Row" - }, - { - "collapse": false, - "editable": true, - "height": "250px", - "panels": [ - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "decimals": null, - "editable": true, - "error": false, - "fill": 0, - "grid": {}, - "id": 1, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "etcd_mvcc_db_total_size_in_bytes{job=\"$cluster\"}", - "hide": false, - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} DB Size", - "metric": "", - "refId": "A", - "step": 4 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "DB Size", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "bytes", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": false - } - ] - }, - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fill": 0, - "grid": {}, - "id": 3, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 1, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 4, - "stack": false, - "steppedLine": true, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_wal_fsync_duration_seconds_bucket{job=\"$cluster\"}[$__rate_interval])) by (instance, le))", - "hide": false, - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} WAL fsync", - "metric": "etcd_disk_wal_fsync_duration_seconds_bucket", - "refId": "A", - "step": 4 - }, - { - "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_backend_commit_duration_seconds_bucket{job=\"$cluster\"}[$__rate_interval])) by (instance, le))", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} DB fsync", - "metric": "etcd_disk_backend_commit_duration_seconds_bucket", - "refId": "B", - "step": 4 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Disk Sync Duration", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": false - } - ] - }, - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fill": 0, - "id": 29, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "process_resident_memory_bytes{job=\"$cluster\"}", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Resident Memory", - "metric": "process_resident_memory_bytes", - "refId": "A", - "step": 4 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Memory", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "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 - } - ] - } - ], - "title": "New row" - }, - { - "collapse": false, - "editable": true, - "height": "250px", - "panels": [ - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fill": 5, - "id": 22, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 3, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "rate(etcd_network_client_grpc_received_bytes_total{job=\"$cluster\"}[$__rate_interval])", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Client Traffic In", - "metric": "etcd_network_client_grpc_received_bytes_total", - "refId": "A", - "step": 4 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Client Traffic In", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fill": 5, - "id": 21, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 3, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "rate(etcd_network_client_grpc_sent_bytes_total{job=\"$cluster\"}[$__rate_interval])", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Client Traffic Out", - "metric": "etcd_network_client_grpc_sent_bytes_total", - "refId": "A", - "step": 4 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Client Traffic Out", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fill": 0, - "id": 20, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(etcd_network_peer_received_bytes_total{job=\"$cluster\"}[$__rate_interval])) by (instance)", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Peer Traffic In", - "metric": "etcd_network_peer_received_bytes_total", - "refId": "A", - "step": 4 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Peer Traffic In", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "decimals": null, - "editable": true, - "error": false, - "fill": 0, - "grid": {}, - "id": 16, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(etcd_network_peer_sent_bytes_total{job=\"$cluster\"}[$__rate_interval])) by (instance)", - "hide": false, - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Peer Traffic Out", - "metric": "etcd_network_peer_sent_bytes_total", - "refId": "A", - "step": 4 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Peer Traffic Out", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "Bps", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "title": "New row" - }, - { - "collapse": false, - "editable": true, - "height": "250px", - "panels": [ - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fill": 0, - "id": 40, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(etcd_server_proposals_failed_total{job=\"$cluster\"}[$__rate_interval]))", - "intervalFactor": 2, - "legendFormat": "Proposal Failure Rate", - "metric": "etcd_server_proposals_failed_total", - "refId": "A", - "step": 2 - }, - { - "expr": "sum(etcd_server_proposals_pending{job=\"$cluster\"})", - "intervalFactor": 2, - "legendFormat": "Proposal Pending Total", - "metric": "etcd_server_proposals_pending", - "refId": "B", - "step": 2 - }, - { - "expr": "sum(rate(etcd_server_proposals_committed_total{job=\"$cluster\"}[$__rate_interval]))", - "intervalFactor": 2, - "legendFormat": "Proposal Commit Rate", - "metric": "etcd_server_proposals_committed_total", - "refId": "C", - "step": 2 - }, - { - "expr": "sum(rate(etcd_server_proposals_applied_total{job=\"$cluster\"}[$__rate_interval]))", - "intervalFactor": 2, - "legendFormat": "Proposal Apply Rate", - "refId": "D", - "step": 2 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Raft Proposals", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": {}, - "bars": false, - "datasource": "$datasource", - "decimals": 0, - "editable": true, - "error": false, - "fill": 0, - "id": 19, - "isNew": true, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "changes(etcd_server_leader_changes_seen_total{job=\"$cluster\"}[1d])", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Total Leader Elections Per Day", - "metric": "etcd_server_leader_changes_seen_total", - "refId": "A", - "step": 2 - } - ], - "thresholds": [], - "timeFrom": null, - "timeShift": null, - "title": "Total Leader Elections Per Day", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "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 - } - ] - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": 0, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 0, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 28 - }, - "hiddenSeries": false, - "id": 42, - "isNew": true, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.4.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum by (instance, le) (rate(etcd_network_peer_round_trip_time_seconds_bucket{job=\"$cluster\"}[$__rate_interval])))", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Peer round trip time", - "metric": "etcd_network_peer_round_trip_time_seconds_bucket", - "refId": "A", - "step": 2 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Peer round trip time", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:925", - "decimals": null, - "format": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "$$hashKey": "object:926", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "title": "New row" - } - ], - "schemaVersion": 13, - "sharedCrosshair": false, - "style": "dark", - "tags": [ - "etcd-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "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": {{ if (or .Values.grafana.sidecar.dashboards.multicluster.global.enabled .Values.grafana.sidecar.dashboards.multicluster.etcd.enabled) }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": "cluster", - "multi": false, - "name": "cluster", - "options": [], - "query": "label_values(etcd_server_has_leader, job)", - "refresh": 2, - "regex": "", - "sort": 2, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": { - "now": true, - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, - "timezone": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "etcd", - "uid": "c2f4e12cdf69feb95caa41a5a1b423d9", - "version": 215 - } -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/grafana-overview.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/grafana-overview.yaml deleted file mode 100644 index f8c8884d0b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/grafana-overview.yaml +++ /dev/null @@ -1,635 +0,0 @@ -{{- /* -Generated from 'grafana-overview' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "grafana-overview" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - grafana-overview.json: |- - { - "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" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 3085, - "iteration": 1631554945276, - "links": [ - - ], - "panels": [ - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "mappings": [ - - ], - "noValue": "0", - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - - ] - }, - "gridPos": { - "h": 5, - "w": 6, - "x": 0, - "y": 0 - }, - "id": 6, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "text": { - - }, - "textMode": "auto" - }, - "pluginVersion": "8.1.3", - "targets": [ - { - "expr": "grafana_alerting_result_total{job=~\"$job\", instance=~\"$instance\", state=\"alerting\"}", - "instant": true, - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Firing Alerts", - "type": "stat" - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "mappings": [ - - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - - ] - }, - "gridPos": { - "h": 5, - "w": 6, - "x": 6, - "y": 0 - }, - "id": 8, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "text": { - - }, - "textMode": "auto" - }, - "pluginVersion": "8.1.3", - "targets": [ - { - "expr": "sum(grafana_stat_totals_dashboard{job=~\"$job\", instance=~\"$instance\"})", - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Dashboards", - "type": "stat" - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": { - "align": null, - "displayMode": "auto" - }, - "mappings": [ - - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - - ] - }, - "gridPos": { - "h": 5, - "w": 12, - "x": 12, - "y": 0 - }, - "id": 10, - "options": { - "showHeader": true - }, - "pluginVersion": "8.1.3", - "targets": [ - { - "expr": "grafana_build_info{job=~\"$job\", instance=~\"$instance\"}", - "instant": true, - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Build Info", - "transformations": [ - { - "id": "labelsToFields", - "options": { - - } - }, - { - "id": "organize", - "options": { - "excludeByName": { - "Time": true, - "Value": true, - "branch": true, - "container": true, - "goversion": true, - "namespace": true, - "pod": true, - "revision": true - }, - "indexByName": { - "Time": 7, - "Value": 11, - "branch": 4, - "container": 8, - "edition": 2, - "goversion": 6, - "instance": 1, - "job": 0, - "namespace": 9, - "pod": 10, - "revision": 5, - "version": 3 - }, - "renameByName": { - - } - } - } - ], - "type": "table" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "links": [ - - ] - }, - "overrides": [ - - ] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 5 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (status_code) (irate(grafana_http_request_duration_seconds_count{job=~\"$job\", instance=~\"$instance\"}[1m])) ", - "interval": "", - "legendFormat": "{{`{{`}}status_code{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeRegions": [ - - ], - "timeShift": null, - "title": "RPS", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "$$hashKey": "object:157", - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "$$hashKey": "object:158", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": false - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "links": [ - - ] - }, - "overrides": [ - - ] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 5 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "exemplar": true, - "expr": "histogram_quantile(0.99, sum(irate(grafana_http_request_duration_seconds_bucket{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) by (le)) * 1", - "interval": "", - "legendFormat": "99th Percentile", - "refId": "A" - }, - { - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(irate(grafana_http_request_duration_seconds_bucket{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) by (le)) * 1", - "interval": "", - "legendFormat": "50th Percentile", - "refId": "B" - }, - { - "exemplar": true, - "expr": "sum(irate(grafana_http_request_duration_seconds_sum{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) * 1 / sum(irate(grafana_http_request_duration_seconds_count{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "Average", - "refId": "C" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeRegions": [ - - ], - "timeShift": null, - "title": "Request Latency", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "$$hashKey": "object:210", - "format": "ms", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "$$hashKey": "object:211", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "schemaVersion": 30, - "style": "dark", - "tags": [ - - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "description": null, - "error": null, - "hide": 0, - "includeAll": false, - "label": "Data Source", - "multi": false, - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "queryValue": "", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "type": "datasource" - }, - { - "allValue": ".*", - "current": { - "selected": false, - "text": [ - "default/grafana" - ], - "value": [ - "default/grafana" - ] - }, - "datasource": "$datasource", - "definition": "label_values(grafana_build_info, job)", - "description": null, - "error": null, - "hide": 0, - "includeAll": true, - "label": null, - "multi": true, - "name": "job", - "options": [ - - ], - "query": { - "query": "label_values(grafana_build_info, job)", - "refId": "Billing Admin-job-Variable-Query" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "selected": false, - "text": "All", - "value": "$__all" - }, - "datasource": "$datasource", - "definition": "label_values(grafana_build_info, instance)", - "description": null, - "error": null, - "hide": 0, - "includeAll": true, - "label": null, - "multi": true, - "name": "instance", - "options": [ - - ], - "query": { - "query": "label_values(grafana_build_info, instance)", - "refId": "Billing Admin-instance-Variable-Query" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-6h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Grafana Overview", - "uid": "6be0s85Mk", - "version": 2 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-coredns.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-coredns.yaml deleted file mode 100644 index 7ecca76f23..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-coredns.yaml +++ /dev/null @@ -1,1534 +0,0 @@ -{{- /* -Generated from 'k8s-coredns' from ../files/dashboards/k8s-coredns.json -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.coreDns.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-coredns" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-coredns.json: |- - { - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "description": "A dashboard for the CoreDNS DNS server with updated metrics for version 1.7.0+. Based on the CoreDNS dashboard by buhay.", - "editable": true, - "gnetId": 12539, - "graphTooltip": 0, - "iteration": 1603798405693, - "links": [ - { - "icon": "external link", - "tags": [], - "targetBlank": true, - "title": "CoreDNS.io", - "type": "link", - "url": "https://coredns.io" - } - ], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [], - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "total", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(coredns_dns_request_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (proto) or\nsum(rate(coredns_dns_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (proto)", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}", - "refId": "A", - "step": 60 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests (total)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "total", - "yaxis": 2 - }, - { - "alias": "other", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(coredns_dns_request_type_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (type) or \nsum(rate(coredns_dns_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (type)", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{type}}"}}", - "refId": "A", - "step": 60 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests (by qtype)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 0 - }, - "hiddenSeries": false, - "id": 6, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "total", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(coredns_dns_request_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (zone) or\nsum(rate(coredns_dns_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (zone)", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{zone}}"}}", - "refId": "A", - "step": 60 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests (by zone)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 8, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "total", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(coredns_dns_request_do_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) or\nsum(rate(coredns_dns_do_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m]))", - "interval": "", - "intervalFactor": 2, - "legendFormat": "DO", - "refId": "A", - "step": 40 - }, - { - "expr": "sum(rate(coredns_dns_request_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) or\nsum(rate(coredns_dns_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m]))", - "interval": "", - "intervalFactor": 2, - "legendFormat": "total", - "refId": "B", - "step": 40 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests (DO bit)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 6, - "x": 12, - "y": 7 - }, - "hiddenSeries": false, - "id": 10, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "tcp:90", - "yaxis": 2 - }, - { - "alias": "tcp:99 ", - "yaxis": 2 - }, - { - "alias": "tcp:50", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:99 ", - "refId": "A", - "step": 60 - }, - { - "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:90", - "refId": "B", - "step": 60 - }, - { - "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:50", - "refId": "C", - "step": 60 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests (size, udp)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "bytes", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 6, - "x": 18, - "y": 7 - }, - "hiddenSeries": false, - "id": 12, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "tcp:90", - "yaxis": 1 - }, - { - "alias": "tcp:99 ", - "yaxis": 1 - }, - { - "alias": "tcp:50", - "yaxis": 1 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:99 ", - "refId": "A", - "step": 60 - }, - { - "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:90", - "refId": "B", - "step": 60 - }, - { - "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:50", - "refId": "C", - "step": 60 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests (size,tcp)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "bytes", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 14, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(coredns_dns_response_rcode_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (rcode) or\nsum(rate(coredns_dns_responses_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (rcode)", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{rcode}}"}}", - "refId": "A", - "step": 40 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Responses (by rcode)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 14 - }, - "hiddenSeries": false, - "id": 32, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_duration_seconds_bucket{job=\"coredns\",instance=~\"$instance\"}[5m])) by (le, job))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "99%", - "refId": "A", - "step": 40 - }, - { - "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_duration_seconds_bucket{job=\"coredns\",instance=~\"$instance\"}[5m])) by (le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "90%", - "refId": "B", - "step": 40 - }, - { - "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_duration_seconds_bucket{job=\"coredns\",instance=~\"$instance\"}[5m])) by (le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "50%", - "refId": "C", - "step": 40 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Responses (duration)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 21 - }, - "hiddenSeries": false, - "id": 18, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "udp:50%", - "yaxis": 1 - }, - { - "alias": "tcp:50%", - "yaxis": 2 - }, - { - "alias": "tcp:90%", - "yaxis": 2 - }, - { - "alias": "tcp:99%", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:99%", - "refId": "A", - "step": 40 - }, - { - "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:90%", - "refId": "B", - "step": 40 - }, - { - "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", - "hide": false, - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:50%", - "metric": "", - "refId": "C", - "step": 40 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Responses (size, udp)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "bytes", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 21 - }, - "hiddenSeries": false, - "id": 20, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "udp:50%", - "yaxis": 1 - }, - { - "alias": "tcp:50%", - "yaxis": 1 - }, - { - "alias": "tcp:90%", - "yaxis": 1 - }, - { - "alias": "tcp:99%", - "yaxis": 1 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto)) ", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:99%", - "refId": "A", - "step": 40 - }, - { - "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto)) ", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:90%", - "refId": "B", - "step": 40 - }, - { - "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le, proto)) ", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{"{{proto}}"}}:50%", - "metric": "", - "refId": "C", - "step": 40 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Responses (size, tcp)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "bytes", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 28 - }, - "hiddenSeries": false, - "id": 22, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(coredns_cache_size{job=\"coredns\",instance=~\"$instance\"}) by (type) or\nsum(coredns_cache_entries{job=\"coredns\",instance=~\"$instance\"}) by (type)", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{"{{type}}"}}", - "refId": "A", - "step": 40 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Cache (size)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "decbytes", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {}, - "links": [] - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 28 - }, - "hiddenSeries": false, - "id": 24, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "misses", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(coredns_cache_hits_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (type)", - "hide": false, - "intervalFactor": 2, - "legendFormat": "hits:{{"{{type}}"}}", - "refId": "A", - "step": 40 - }, - { - "expr": "sum(rate(coredns_cache_misses_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (type)", - "hide": false, - "intervalFactor": 2, - "legendFormat": "misses", - "refId": "B", - "step": 40 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Cache (hitrate)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": "10s", - "schemaVersion": 26, - "style": "dark", - "tags": [ - "dns", - "coredns" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "includeAll": false, - "label": "Data Source", - "multi": false, - "name": "datasource", - "options": [], - "query": "prometheus", - "queryValue": "", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "type": "datasource" - }, - { - "allValue": ".*", - "current": { - "selected": true, - "text": "All", - "value": "$__all" - }, - "datasource": "$datasource", - "definition": "label_values(up{job=\"coredns\"}, instance)", - "hide": 0, - "includeAll": true, - "label": "Instance", - "multi": false, - "name": "instance", - "options": [], - "query": "label_values(up{job=\"coredns\"}, instance)", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 3, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-3h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "CoreDNS", - "uid": "vkQ0UHxik", - "version": 2 - } -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml deleted file mode 100644 index 5c1193274e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml +++ /dev/null @@ -1,3088 +0,0 @@ -{{- /* -Generated from 'k8s-resources-cluster' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-cluster" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-cluster.json: |- - { - "annotations": { - "list": [ - - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "height": "100px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "format": "percentunit", - "id": 1, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 2, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "cluster:node_cpu:ratio_rate5m{cluster=\"$cluster\"}", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "CPU Utilisation", - "tooltip": { - "shared": false, - "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": "percentunit", - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 2, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\",cluster=\"$cluster\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "CPU Requests Commitment", - "tooltip": { - "shared": false, - "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": "percentunit", - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 2, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\",cluster=\"$cluster\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "CPU Limits Commitment", - "tooltip": { - "shared": false, - "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": "percentunit", - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 2, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "1 - sum(:node_memory_MemAvailable_bytes:sum{cluster=\"$cluster\"}) / sum(node_memory_MemTotal_bytes{job=\"node-exporter\",cluster=\"$cluster\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "Memory Utilisation", - "tooltip": { - "shared": false, - "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": "percentunit", - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 2, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\",cluster=\"$cluster\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "Memory Requests Commitment", - "tooltip": { - "shared": false, - "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": "percentunit", - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 2, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\",cluster=\"$cluster\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "Memory Limits Commitment", - "tooltip": { - "shared": false, - "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": 10, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\"}) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Usage", - "tooltip": { - "shared": false, - "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": "CPU", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Pods", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 0, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell_1", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Workloads", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 0, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to workloads", - "linkUrl": "d/a87fb0d919ec0ea5f6543124e16c42a5/k8s-resources-workloads-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell_1", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "CPU Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #G", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Namespace", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell", - "pattern": "namespace", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(kube_pod_owner{job=\"kube-state-metrics\", cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "count(avg(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\"}) by (workload, namespace)) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\"}) by (namespace) / sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\"}) by (namespace) / sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "G", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "CPU Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 9, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Usage (w/o cache)", - "tooltip": { - "shared": false, - "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": "Memory", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Pods", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 0, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell_1", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Workloads", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 0, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to workloads", - "linkUrl": "d/a87fb0d919ec0ea5f6543124e16c42a5/k8s-resources-workloads-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell_1", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Memory Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #G", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Namespace", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell", - "pattern": "namespace", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(kube_pod_owner{job=\"kube-state-metrics\", cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "count(avg(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\"}) by (workload, namespace)) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace) / sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - }, - { - "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace) / sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "G", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Requests by Namespace", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Memory Requests", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 11, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Current Receive Bandwidth", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Current Transmit Bandwidth", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Rate of Received Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Received Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Namespace", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell", - "pattern": "namespace", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Network Usage", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Current Network Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 12, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "tooltip": { - "shared": false, - "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, - "id": 13, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 14, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "avg(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Container Bandwidth by Namespace: Received", - "tooltip": { - "shared": false, - "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, - "id": 15, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "avg(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Container Bandwidth by Namespace: Transmitted", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Average Container Bandwidth by Namespace", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 16, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 17, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 18, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 19, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets Dropped", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": -1, - "fill": 10, - "id": 20, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "ceil(sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval])))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "IOPS(Reads+Writes)", - "tooltip": { - "shared": false, - "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": 21, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}namespace{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "ThroughPut(Read+Write)", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Storage IO", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 22, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - - ], - "sort": { - "col": 4, - "desc": true - }, - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "IOPS(Reads)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "IOPS(Writes)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "IOPS(Reads + Writes)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Throughput(Read)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Throughput(Write)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Throughput(Read + Write)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Namespace", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell", - "pattern": "namespace", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum by(namespace) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum by(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum by(namespace) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum by(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Storage IO", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Storage IO - Distribution", - "titleSize": "h6" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Compute Resources / Cluster", - "uid": "efa86fd1d0c121a26444b636a3f509a8", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml deleted file mode 100644 index 75e1584201..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- /* -Generated from 'k8s-resources-multicluster' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-multicluster" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-multicluster.json: |- - {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"none"}},"gridPos":{"h":3,"w":4,"x":0,"y":0},"id":1,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"cluster:node_cpu:ratio_rate5m","instant":true}],"title":"CPU Utilisation","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":4,"y":0},"id":2,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"cpu\"})","instant":true}],"title":"CPU Requests Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":8,"y":0},"id":3,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"cpu\"})","instant":true}],"title":"CPU Limits Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":12,"y":0},"id":4,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"1 - sum(:node_memory_MemAvailable_bytes:sum) / sum(node_memory_MemTotal_bytes{job=\"node-exporter\"})","instant":true}],"title":"Memory Utilisation","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":16,"y":0},"id":5,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"memory\"})","instant":true}],"title":"Memory Requests Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":20,"y":0},"id":6,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"memory\"})","instant":true}],"title":"Memory Limits Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"showPoints":"never"}}},"gridPos":{"h":7,"w":24,"x":0,"y":1},"id":7,"interval":"1m","options":{"legend":{"asTable":true,"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster)","legendFormat":"__auto"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Cluster"},"properties":[{"id":"links","value":[{"title":"Drill down","url":"/d/efa86fd1d0c121a26444b636a3f509a8/kubernetes-compute-resources-cluster?${datasource:queryparam}&var-cluster=${__data.fields.Cluster}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":2},"id":8,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true}],"title":"CPU Quota","transformations":[{"id":"joinByField","options":{"byField":"cluster","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"cluster":5},"renameByName":{"Value #A":"CPU Usage","Value #B":"CPU Requests","Value #C":"CPU Requests %","Value #D":"CPU Limits","Value #E":"CPU Limits %","cluster":"Cluster"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"showPoints":"never"},"unit":"bytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":3},"id":9,"interval":"1m","options":{"legend":{"asTable":true,"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster)","legendFormat":"__auto"}],"title":"Memory Usage (w/o cache)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Cluster"},"properties":[{"id":"links","value":[{"title":"Drill down","url":"/d/efa86fd1d0c121a26444b636a3f509a8/kubernetes-compute-resources-cluster?${datasource:queryparam}&var-cluster=${__data.fields.Cluster}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":4},"id":10,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true}],"title":"Memory Requests by Cluster","transformations":[{"id":"joinByField","options":{"byField":"cluster","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"cluster":5},"renameByName":{"Value #A":"Memory Usage","Value #B":"Memory Requests","Value #C":"Memory Requests %","Value #D":"Memory Limits","Value #E":"Memory Limits %","cluster":"Cluster"}}}],"type":"table"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Multi-Cluster","uid":"b59e6c9f2fcbe2e16d77fc492374cc4f"}`}} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml deleted file mode 100644 index 896b0b2d92..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml +++ /dev/null @@ -1,2797 +0,0 @@ -{{- /* -Generated from 'k8s-resources-namespace' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-namespace" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-namespace.json: |- - { - "annotations": { - "list": [ - - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "height": "100px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "format": "percentunit", - "id": 1, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "CPU Utilisation (from requests)", - "tooltip": { - "shared": false, - "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": "percentunit", - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "CPU Utilisation (from limits)", - "tooltip": { - "shared": false, - "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": "percentunit", - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "Memory Utilisation (from requests)", - "tooltip": { - "shared": false, - "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": "percentunit", - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"})", - "format": "time_series", - "instant": true, - "intervalFactor": 2, - "refId": "A" - } - ], - "thresholds": "70,80", - "timeFrom": null, - "timeShift": null, - "title": "Memory Utilisation (from limits)", - "tooltip": { - "shared": false, - "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": 10, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "quota - requests", - "color": "#F2495C", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - }, - { - "alias": "quota - limits", - "color": "#FF9830", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - } - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.cpu\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "quota - requests", - "legendLink": null, - "step": 10 - }, - { - "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.cpu\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "quota - limits", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Usage", - "tooltip": { - "shared": false, - "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": "CPU Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "CPU Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "CPU Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "CPU Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "quota - requests", - "color": "#F2495C", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - }, - { - "alias": "quota - limits", - "color": "#FF9830", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - } - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.memory\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "quota - requests", - "legendLink": null, - "step": 10 - }, - { - "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.memory\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "quota - limits", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Usage (w/o cache)", - "tooltip": { - "shared": false, - "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": "Memory Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Memory Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Usage (RSS)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Usage (Cache)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #G", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Usage (Swap)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #H", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - }, - { - "expr": "sum(container_memory_cache{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "G", - "step": 10 - }, - { - "expr": "sum(container_memory_swap{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "H", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Memory Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 9, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Current Receive Bandwidth", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Current Transmit Bandwidth", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Rate of Received Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Received Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Network Usage", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Current Network Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "tooltip": { - "shared": false, - "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, - "id": 11, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 12, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 13, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 14, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 15, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets Dropped", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": -1, - "fill": 10, - "id": 16, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "ceil(sum by(pod) (rate(container_fs_reads_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "IOPS(Reads+Writes)", - "tooltip": { - "shared": false, - "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": 17, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(pod) (rate(container_fs_reads_bytes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "ThroughPut(Read+Write)", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Storage IO", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 18, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - - ], - "sort": { - "col": 4, - "desc": true - }, - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "IOPS(Reads)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "IOPS(Writes)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "IOPS(Reads + Writes)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Throughput(Read)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Throughput(Write)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Throughput(Read + Write)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum by(pod) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum by(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum by(pod) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum by(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Storage IO", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Storage IO - Distribution", - "titleSize": "h6" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Compute Resources / Namespace (Pods)", - "uid": "85a562078cdf77779eaa1add43ccec1e", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-node.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-node.yaml deleted file mode 100644 index ab9c76efe0..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-node.yaml +++ /dev/null @@ -1,1026 +0,0 @@ -{{- /* -Generated from 'k8s-resources-node' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-node" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-node.json: |- - { - "annotations": { - "list": [ - - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 1, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "max capacity", - "color": "#F2495C", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - } - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(kube_node_status_capacity{cluster=\"$cluster\", node=~\"$node\", resource=\"cpu\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "max capacity", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Usage", - "tooltip": { - "shared": false, - "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": "CPU Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "CPU Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "CPU Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", node=~\"$node\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", node=~\"$node\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "CPU Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "max capacity", - "color": "#F2495C", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - } - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(kube_node_status_capacity{cluster=\"$cluster\", node=~\"$node\", resource=\"memory\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "max capacity", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\", container!=\"\"}) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Usage (w/o cache)", - "tooltip": { - "shared": false, - "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": "Memory Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Memory Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Usage (RSS)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Usage (Cache)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #G", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Usage (Swap)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #H", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_memory_rss{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_memory_cache{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "G", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_memory_swap{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "H", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Memory Quota", - "titleSize": "h6" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": true, - "name": "node", - "options": [ - - ], - "query": "label_values(kube_node_info{cluster=\"$cluster\"}, node)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Compute Resources / Node (Pods)", - "uid": "200ac8fdbfbb74b39aff88118e4d1c2c", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml deleted file mode 100644 index 0a6da86c15..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml +++ /dev/null @@ -1,2469 +0,0 @@ -{{- /* -Generated from 'k8s-resources-pod' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-pod" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-pod.json: |- - { - "annotations": { - "list": [ - - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 1, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "requests", - "color": "#F2495C", - "fill": 0, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - }, - { - "alias": "limits", - "color": "#FF9830", - "fill": 0, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - } - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$namespace\", pod=\"$pod\", cluster=\"$cluster\"}) by (container)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}container{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"cpu\"}\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "requests", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"cpu\"}\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "limits", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Usage", - "tooltip": { - "shared": false, - "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": "CPU Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": true, - "min": false, - "rightSide": true, - "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": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(increase(container_cpu_cfs_throttled_periods_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", cluster=\"$cluster\"}[$__rate_interval])) by (container) /sum(increase(container_cpu_cfs_periods_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", cluster=\"$cluster\"}[$__rate_interval])) by (container)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}container{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - { - "colorMode": "critical", - "fill": true, - "line": true, - "op": "gt", - "value": 0.25, - "yaxis": "left" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Throttling", - "tooltip": { - "shared": false, - "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": 1, - "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": "CPU Throttling", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "CPU Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "CPU Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Container", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "container", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "CPU Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "requests", - "color": "#F2495C", - "dashes": true, - "fill": 0, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - }, - { - "alias": "limits", - "color": "#FF9830", - "dashes": true, - "fill": 0, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - } - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}container{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"memory\"}\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "requests", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"memory\"}\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "limits", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Usage (WSS)", - "tooltip": { - "shared": false, - "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": "Memory Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Memory Usage (WSS)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Usage (RSS)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Usage (Cache)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #G", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Usage (Swap)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #H", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Container", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "container", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", image!=\"\"}) by (container) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - }, - { - "expr": "sum(container_memory_cache{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "G", - "step": 10 - }, - { - "expr": "sum(container_memory_swap{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "H", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Memory Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "tooltip": { - "shared": false, - "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, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 11, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets Dropped", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": -1, - "fill": 10, - "id": 12, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "ceil(sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Reads", - "legendLink": null, - "step": 10 - }, - { - "expr": "ceil(sum by(pod) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\",namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Writes", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "IOPS", - "tooltip": { - "shared": false, - "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": 13, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Reads", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum by(pod) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Writes", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "ThroughPut", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Storage IO - Distribution(Pod - Read & Writes)", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": -1, - "fill": 10, - "id": 14, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "ceil(sum by(container) (rate(container_fs_reads_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval])))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}container{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "IOPS(Reads+Writes)", - "tooltip": { - "shared": false, - "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": 15, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(container) (rate(container_fs_reads_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}container{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "ThroughPut(Read+Write)", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Storage IO - Distribution(Containers)", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 16, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - - ], - "sort": { - "col": 4, - "desc": true - }, - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "IOPS(Reads)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "IOPS(Writes)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "IOPS(Reads + Writes)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": -1, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Throughput(Read)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Throughput(Write)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Throughput(Read + Write)", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Container", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "container", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum by(container) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum by(container) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\",device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum by(container) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum by(container) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum by(container) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum by(container) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Storage IO", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Storage IO - Distribution", - "titleSize": "h6" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "pod", - "options": [ - - ], - "query": "label_values(kube_pod_info{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\"}, pod)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Compute Resources / Pod", - "uid": "6581e46e4e5c7ba40a07646395ef7b23", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml deleted file mode 100644 index 6def97a796..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- /* -Generated from 'k8s-resources-windows-cluster' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-windows-cluster" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-windows-cluster.json: |- - {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"none"}},"gridPos":{"h":3,"w":4,"x":0,"y":0},"id":1,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"1 - avg(rate(windows_cpu_time_total{cluster=\"$cluster\", job=\"windows-exporter\", mode=\"idle\"}[1m]))","instant":true}],"title":"CPU Utilisation","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":4,"y":0},"id":2,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) / sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"})","instant":true}],"title":"CPU Requests Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":8,"y":0},"id":3,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) / sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"})","instant":true}],"title":"CPU Limits Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":12,"y":0},"id":4,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"1 - sum(:windows_node_memory_MemFreeCached_bytes:sum{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","instant":true}],"title":"Memory Utilisation","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":16,"y":0},"id":5,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","instant":true}],"title":"Memory Requests Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":20,"y":0},"id":6,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","instant":true}],"title":"Memory Limits Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true}}},"gridPos":{"h":7,"w":24,"x":0,"y":7},"id":7,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace)","legendFormat":"__auto"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Namespace"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":14},"id":8,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true}],"title":"CPU Quota","transformations":[{"id":"joinByField","options":{"byField":"namespace","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"namespace":5},"renameByName":{"Value #A":"CPU Usage","Value #B":"CPU Requests","Value #C":"CPU Requests %","Value #D":"CPU Limits","Value #E":"CPU Limits %","namespace":"Namespace"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"decbytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":21},"id":9,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace)","legendFormat":"__auto"}],"title":"Memory Usage (Private Working Set)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Memory Usage"},"properties":[{"id":"unit","value":"decbytes"}]},{"matcher":{"id":"byName","options":"Memory Requests"},"properties":[{"id":"unit","value":"decbytes"}]},{"matcher":{"id":"byName","options":"Memory Limits"},"properties":[{"id":"unit","value":"decbytes"}]},{"matcher":{"id":"byName","options":"Namespace"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":28},"id":10,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true}],"title":"Memory Requests by Namespace","transformations":[{"id":"joinByField","options":{"byField":"namespace","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"namespace":5},"renameByName":{"Value #A":"Memory Usage","Value #B":"Memory Requests","Value #C":"Memory Requests %","Value #D":"Memory Limits","Value #E":"Memory Limits %","namespace":"Namespace"}}}],"type":"table"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Cluster(Windows)","uid":"4d08557fd9391b100730f2494bccac68"}`}} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml deleted file mode 100644 index 2dfd58bed1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- /* -Generated from 'k8s-resources-windows-namespace' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-windows-namespace" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-windows-namespace.json: |- - {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true}}},"gridPos":{"h":7,"w":24,"x":0,"y":0},"id":1,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","legendFormat":"__auto"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Pod"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":7},"id":2,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true}],"title":"CPU Quota","transformations":[{"id":"joinByField","options":{"byField":"pod","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"pod":5},"renameByName":{"Value #A":"CPU Usage","Value #B":"CPU Requests","Value #C":"CPU Requests %","Value #D":"CPU Limits","Value #E":"CPU Limits %","pod":"Pod"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"decbytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":14},"id":3,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","legendFormat":"__auto"}],"title":"Memory Usage (Private Working Set)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Pod"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":21},"id":4,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true}],"title":"Memory Quota","transformations":[{"id":"joinByField","options":{"byField":"pod","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"pod":5},"renameByName":{"Value #A":"Memory Usage","Value #B":"Memory Requests","Value #C":"Memory Requests %","Value #D":"Memory Limits","Value #E":"Memory Limits %","pod":"Pod"}}}],"type":"table"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":0,"label":"namespace","name":"namespace","query":"label_values(windows_pod_container_available{cluster=\"$cluster\"}, namespace)","refresh":2,"sort":1,"type":"query"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Namespace(Windows)","uid":"490b402361724ab1d4c45666c1fa9b6f"}`}} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml deleted file mode 100644 index 4417b31a6e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- /* -Generated from 'k8s-resources-windows-pod' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-windows-pod" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-windows-pod.json: |- - {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true}}},"gridPos":{"h":7,"w":24,"x":0,"y":0},"id":1,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","legendFormat":"__auto"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Namespace"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":7},"id":2,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true}],"title":"CPU Quota","transformations":[{"id":"joinByField","options":{"byField":"container","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"container":5},"renameByName":{"Value #A":"CPU Usage","Value #B":"CPU Requests","Value #C":"CPU Requests %","Value #D":"CPU Limits","Value #E":"CPU Limits %","container":"Container"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"decbytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":14},"id":3,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","legendFormat":"__auto"}],"title":"Memory Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":21},"id":4,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true}],"title":"Memory Quota","transformations":[{"id":"joinByField","options":{"byField":"container","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"container":5},"renameByName":{"Value #A":"Memory Usage","Value #B":"Memory Requests","Value #C":"Memory Requests %","Value #D":"Memory Limits","Value #E":"Memory Limits %","container":"Container"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"bytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":28},"id":5,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sort_desc(sum by (container) (rate(windows_container_network_received_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[1m])))","legendFormat":"Received : {{ container }}"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sort_desc(sum by (container) (rate(windows_container_network_transmitted_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[1m])))","legendFormat":"Transmitted : {{ container }}"}],"title":"Network I/O","type":"timeseries"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":0,"label":"namespace","name":"namespace","query":"label_values(windows_pod_container_available{cluster=\"$cluster\"}, namespace)","refresh":2,"sort":1,"type":"query"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":0,"label":"pod","name":"pod","query":"label_values(windows_pod_container_available{cluster=\"$cluster\",namespace=\"$namespace\"}, pod)","refresh":2,"sort":1,"type":"query"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Pod(Windows)","uid":"40597a704a610e936dc6ed374a7ce023"}`}} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml deleted file mode 100644 index a1bd68b805..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml +++ /dev/null @@ -1,2024 +0,0 @@ -{{- /* -Generated from 'k8s-resources-workload' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-workload" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-workload.json: |- - { - "annotations": { - "list": [ - - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 1, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Usage", - "tooltip": { - "shared": false, - "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": "CPU Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "CPU Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "CPU Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "CPU Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Usage", - "tooltip": { - "shared": false, - "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": "Memory Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Memory Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Memory Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Current Receive Bandwidth", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Current Transmit Bandwidth", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Rate of Received Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Received Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "(sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Network Usage", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Current Network Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "tooltip": { - "shared": false, - "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, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "(avg(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Container Bandwidth by Pod: Received", - "tooltip": { - "shared": false, - "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, - "id": 9, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "(avg(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Container Bandwidth by Pod: Transmitted", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Average Container Bandwidth by Pod", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 11, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 12, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 13, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets Dropped", - "titleSize": "h6" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "type", - "options": [ - - ], - "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\"}, workload_type)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "workload", - "options": [ - - ], - "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}, workload)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Compute Resources / Workload", - "uid": "a164a7f0339f99e89cea5cb47e9be617", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml deleted file mode 100644 index 09257b911e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml +++ /dev/null @@ -1,2189 +0,0 @@ -{{- /* -Generated from 'k8s-resources-workloads-namespace' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-workloads-namespace" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-resources-workloads-namespace.json: |- - { - "annotations": { - "list": [ - - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 1, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "quota - requests", - "color": "#F2495C", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - }, - { - "alias": "quota - limits", - "color": "#FF9830", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - } - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}} - {{`{{`}}workload_type{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.cpu\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "quota - requests", - "legendLink": null, - "step": 10 - }, - { - "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.cpu\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "quota - limits", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Usage", - "tooltip": { - "shared": false, - "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": "CPU Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Running Pods", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 0, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "CPU Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "CPU Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Workload", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-workload=$__cell&var-type=$__cell_2", - "pattern": "workload", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Workload Type", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "workload_type", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "count(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload, workload_type)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "CPU Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [ - - ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "quota - requests", - "color": "#F2495C", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - }, - { - "alias": "quota - limits", - "color": "#FF9830", - "dashes": true, - "fill": 0, - "hiddenSeries": true, - "hideTooltip": true, - "legend": true, - "linewidth": 2, - "stack": false - } - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(\n container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}} - {{`{{`}}workload_type{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.memory\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "quota - requests", - "legendLink": null, - "step": 10 - }, - { - "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.memory\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "quota - limits", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Usage", - "tooltip": { - "shared": false, - "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": "Memory Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Running Pods", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 0, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Memory Usage", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Requests %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Memory Limits", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "bytes" - }, - { - "alias": "Memory Limits %", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "percentunit" - }, - { - "alias": "Workload", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-workload=$__cell&var-type=$__cell_2", - "pattern": "workload", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Workload Type", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "workload_type", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "count(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload, workload_type)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(\n container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(\n container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(\n container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Quota", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Memory Quota", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Current Receive Bandwidth", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Current Transmit Bandwidth", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Rate of Received Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Received Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Workload", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTargetBlank": false, - "linkTooltip": "Drill down to pods", - "linkUrl": "d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-workload=$__cell&var-type=$type", - "pattern": "workload", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Workload Type", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "workload_type", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "(sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "(sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Network Usage", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Current Network Usage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "tooltip": { - "shared": false, - "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, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "(avg(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Container Bandwidth by Workload: Received", - "tooltip": { - "shared": false, - "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, - "id": 9, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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": "(avg(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Container Bandwidth by Workload: Transmitted", - "tooltip": { - "shared": false, - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Average Container Bandwidth by Workload", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 11, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 12, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": 13, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "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(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "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": "Rate of Packets Dropped", - "titleSize": "h6" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(kube_pod_info{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "deployment", - "value": "deployment" - }, - "datasource": "$datasource", - "definition": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\"}, workload_type)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "type", - "options": [ - - ], - "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\"}, workload_type)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Compute Resources / Namespace (Workloads)", - "uid": "a87fb0d919ec0ea5f6543124e16c42a5", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml deleted file mode 100644 index 0c4a2ca998..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- /* -Generated from 'k8s-windows-cluster-rsrc-use' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-windows-cluster-rsrc-use" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-windows-cluster-rsrc-use.json: |- - {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":24,"x":0,"y":0},"id":1,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_cpu_utilisation:avg1m{cluster=\"$cluster\"} * node:windows_node_num_cpu:sum{cluster=\"$cluster\"} / scalar(sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"}))","legendFormat":"{{instance}}"}],"title":"CPU Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":12,"x":0,"y":7},"id":2,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_memory_utilisation:ratio{cluster=\"$cluster\"}","legendFormat":"{{instance}}"}],"title":"Memory Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"short"}},"gridPos":{"h":7,"w":12,"x":12,"y":7},"id":3,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_memory_swap_io_pages:irate{cluster=\"$cluster\"}","legendFormat":"{{instance}}"}],"title":"Memory Saturation (Swap I/O Pages)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":24,"x":0,"y":14},"id":4,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_disk_utilisation:avg_irate{cluster=\"$cluster\"} / scalar(node:windows_node:sum{cluster=\"$cluster\"})","legendFormat":"{{instance}}"}],"title":"Disk IO Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"Bps"}},"gridPos":{"h":7,"w":12,"x":0,"y":21},"id":5,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_net_utilisation:sum_irate{cluster=\"$cluster\"}","legendFormat":"{{instance}}"}],"title":"Net Utilisation (Transmitted)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"Bps"}},"gridPos":{"h":7,"w":12,"x":12,"y":21},"id":6,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_net_saturation:sum_irate{cluster=\"$cluster\"}","legendFormat":"{{instance}}"}],"title":"Net Utilisation (Dropped)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":24,"x":0,"y":28},"id":7,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum by (instance)(node:windows_node_filesystem_usage:{cluster=\"$cluster\"})","legendFormat":"{{instance}}"}],"title":"Disk Capacity","type":"timeseries"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / USE Method / Cluster(Windows)","uid":"53a43377ec9aaf2ff64dfc7a1f539334"}`}} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml deleted file mode 100644 index 890cef3a8d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- /* -Generated from 'k8s-windows-node-rsrc-use' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-windows-node-rsrc-use" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - k8s-windows-node-rsrc-use.json: |- - {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":12,"x":0,"y":0},"id":1,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_cpu_utilisation:avg1m{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Utilisation"}],"title":"CPU Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":12,"x":12,"y":0},"id":2,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum by (core) (irate(windows_cpu_time_total{cluster=\"$cluster\", job=\"windows-exporter\", mode!=\"idle\", instance=\"$instance\"}[$__rate_interval]))","legendFormat":"{{core}}"}],"title":"CPU Usage Per Core","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":8,"x":0,"y":7},"id":3,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_memory_utilisation:{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Memory"}],"title":"Memory Utilisation %","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"bytes"}},"gridPos":{"h":7,"w":8,"x":8,"y":7},"id":4,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(\n windows_os_visible_memory_bytes{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}\n - windows_memory_available_bytes{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}\n)\n","legendFormat":"memory used"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(node:windows_node_memory_totalCached_bytes:sum{cluster=\"$cluster\", instance=\"$instance\"})","legendFormat":"memory cached"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(windows_memory_available_bytes{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"})","legendFormat":"memory free"}],"title":"Memory Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"short"}},"gridPos":{"h":7,"w":8,"x":16,"y":7},"id":5,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_memory_swap_io_pages:irate{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Swap IO"}],"title":"Memory Saturation (Swap I/O) Pages","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":12,"x":0,"y":14},"id":6,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_disk_utilisation:avg_irate{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Utilisation"}],"title":"Disk IO Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/io time/"},"properties":[{"id":"unit","value":"ms"}]}]},"gridPos":{"h":7,"w":12,"x":12,"y":14},"id":7,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(rate(windows_logical_disk_read_bytes_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]))","legendFormat":"read"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(rate(windows_logical_disk_write_bytes_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]))","legendFormat":"written"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(rate(windows_logical_disk_read_seconds_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]) + rate(windows_logical_disk_write_seconds_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]))","legendFormat":"io time"}],"title":"Disk IO","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":24,"x":0,"y":21},"id":8,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_filesystem_usage:{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"{{volume}}"}],"title":"Disk Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"Bps"}},"gridPos":{"h":7,"w":12,"x":0,"y":28},"id":9,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_net_utilisation:sum_irate{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Utilisation"}],"title":"Net Utilisation (Transmitted)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"Bps"}},"gridPos":{"h":7,"w":12,"x":12,"y":28},"id":10,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_net_saturation:sum_irate{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Saturation"}],"title":"Net Saturation (Dropped)","type":"timeseries"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":0,"label":"instance","multi":true,"name":"instance","query":"label_values(windows_system_system_up_time{cluster=\"$cluster\"}, instance)","refresh":2,"type":"query"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / USE Method / Node(Windows)","uid":"96e7484b0bb53b74fbc2bcb7723cd40b"}`}} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/kubelet.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/kubelet.yaml deleted file mode 100644 index bdbf1c2195..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/kubelet.yaml +++ /dev/null @@ -1,2256 +0,0 @@ -{{- /* -Generated from 'kubelet' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -{{- if (include "exporter.kubelet.enabled" .) }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "kubelet" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - kubelet.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "panels": [ - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "links": [ - - ], - "mappings": [ - - ], - "thresholds": { - "mode": "absolute", - "steps": [ - - ] - }, - "unit": "none" - } - }, - "gridPos": { - "h": 7, - "w": 4, - "x": 0, - "y": 0 - }, - "id": 2, - "links": [ - - ], - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7", - "targets": [ - { - "expr": "sum(kubelet_node_name{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "title": "Running Kubelets", - "transparent": false, - "type": "stat" - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "links": [ - - ], - "mappings": [ - - ], - "thresholds": { - "mode": "absolute", - "steps": [ - - ] - }, - "unit": "none" - } - }, - "gridPos": { - "h": 7, - "w": 4, - "x": 4, - "y": 0 - }, - "id": 3, - "links": [ - - ], - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7", - "targets": [ - { - "expr": "sum(kubelet_running_pods{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}) OR sum(kubelet_running_pod_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "title": "Running Pods", - "transparent": false, - "type": "stat" - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "links": [ - - ], - "mappings": [ - - ], - "thresholds": { - "mode": "absolute", - "steps": [ - - ] - }, - "unit": "none" - } - }, - "gridPos": { - "h": 7, - "w": 4, - "x": 8, - "y": 0 - }, - "id": 4, - "links": [ - - ], - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7", - "targets": [ - { - "expr": "sum(kubelet_running_containers{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}) OR sum(kubelet_running_container_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "title": "Running Containers", - "transparent": false, - "type": "stat" - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "links": [ - - ], - "mappings": [ - - ], - "thresholds": { - "mode": "absolute", - "steps": [ - - ] - }, - "unit": "none" - } - }, - "gridPos": { - "h": 7, - "w": 4, - "x": 12, - "y": 0 - }, - "id": 5, - "links": [ - - ], - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7", - "targets": [ - { - "expr": "sum(volume_manager_total_volumes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\", state=\"actual_state_of_world\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "title": "Actual Volume Count", - "transparent": false, - "type": "stat" - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "links": [ - - ], - "mappings": [ - - ], - "thresholds": { - "mode": "absolute", - "steps": [ - - ] - }, - "unit": "none" - } - }, - "gridPos": { - "h": 7, - "w": 4, - "x": 16, - "y": 0 - }, - "id": 6, - "links": [ - - ], - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7", - "targets": [ - { - "expr": "sum(volume_manager_total_volumes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",state=\"desired_state_of_world\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "title": "Desired Volume Count", - "transparent": false, - "type": "stat" - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "links": [ - - ], - "mappings": [ - - ], - "thresholds": { - "mode": "absolute", - "steps": [ - - ] - }, - "unit": "none" - } - }, - "gridPos": { - "h": 7, - "w": 4, - "x": 20, - "y": 0 - }, - "id": 7, - "links": [ - - ], - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7", - "targets": [ - { - "expr": "sum(rate(kubelet_node_config_error{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "title": "Config Error Count", - "transparent": false, - "type": "stat" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 7 - }, - "id": 8, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(kubelet_runtime_operations_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (operation_type, instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_type{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Operation Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 7 - }, - "id": 9, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(kubelet_runtime_operations_errors_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_type{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Operation Error Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 14 - }, - "id": 10, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(kubelet_runtime_operations_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_type{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Operation duration 99th quantile", - "tooltip": { - "shared": true, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 21 - }, - "id": 11, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(kubelet_pod_start_duration_seconds_count{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} pod", - "refId": "A" - }, - { - "expr": "sum(rate(kubelet_pod_worker_duration_seconds_count{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} worker", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Pod Start Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 21 - }, - "id": 12, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} pod", - "refId": "A" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(kubelet_pod_worker_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} worker", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Pod Start Duration", - "tooltip": { - "shared": true, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 28 - }, - "id": 13, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(storage_operation_duration_seconds_count{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_name{{`}}`}} {{`{{`}}volume_plugin{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Storage Operation Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 28 - }, - "id": 14, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(storage_operation_errors_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_name{{`}}`}} {{`{{`}}volume_plugin{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Storage Operation Error Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 35 - }, - "id": 15, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(storage_operation_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_name{{`}}`}} {{`{{`}}volume_plugin{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Storage Operation Duration 99th quantile", - "tooltip": { - "shared": true, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 42 - }, - "id": 16, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(kubelet_cgroup_manager_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}operation_type{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Cgroup manager operation rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 42 - }, - "id": 17, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(kubelet_cgroup_manager_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_type{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Cgroup manager 99th quantile", - "tooltip": { - "shared": true, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "Pod lifecycle event generator", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 49 - }, - "id": 18, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(kubelet_pleg_relist_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "PLEG relist rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 49 - }, - "id": 19, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_interval_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "PLEG relist interval", - "tooltip": { - "shared": true, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 56 - }, - "id": 20, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "PLEG relist duration", - "tooltip": { - "shared": true, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 63 - }, - "id": 21, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "2xx", - "refId": "A" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "3xx", - "refId": "B" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "4xx", - "refId": "C" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "5xx", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "RPC Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 70 - }, - "id": 22, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, verb, url, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Request duration 99th quantile", - "tooltip": { - "shared": true, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 77 - }, - "id": 23, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "process_resident_memory_bytes{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory", - "tooltip": { - "shared": true, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 77 - }, - "id": 24, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU usage", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 77 - }, - "id": 25, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "go_goroutines{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Goroutines", - "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 - } - ] - } - ], - "refresh": "10s", - "rows": [ - - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": "cluster", - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": "instance", - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",cluster=\"$cluster\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Kubelet", - "uid": "3138fa155d5915769fbded898ac09fd9", - "version": 0 - } -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-pod.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-pod.yaml deleted file mode 100644 index 92882d7dba..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-pod.yaml +++ /dev/null @@ -1,1464 +0,0 @@ -{{- /* -Generated from 'namespace-by-pod' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "namespace-by-pod" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - namespace-by-pod.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "panels": [ - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 2, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Current Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "decimals": 0, - "format": "time_series", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 1 - }, - "height": 9, - "id": 3, - "interval": null, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "minSpan": 12, - "nullPointMode": "connected", - "nullText": null, - "options": { - "fieldOptions": { - "calcs": [ - "last" - ], - "defaults": { - "max": 10000000000, - "min": 0, - "title": "$namespace", - "unit": "Bps" - }, - "mappings": [ - - ], - "override": { - - }, - "thresholds": [ - { - "color": "dark-green", - "index": 0, - "value": null - }, - { - "color": "dark-yellow", - "index": 1, - "value": 5000000000 - }, - { - "color": "dark-red", - "index": 2, - "value": 7000000000 - } - ], - "values": false - } - }, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 12, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution]))", - "format": "time_series", - "instant": null, - "intervalFactor": 1, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Received", - "type": "gauge", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "decimals": 0, - "format": "time_series", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 1 - }, - "height": 9, - "id": 4, - "interval": null, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "minSpan": 12, - "nullPointMode": "connected", - "nullText": null, - "options": { - "fieldOptions": { - "calcs": [ - "last" - ], - "defaults": { - "max": 10000000000, - "min": 0, - "title": "$namespace", - "unit": "Bps" - }, - "mappings": [ - - ], - "override": { - - }, - "thresholds": [ - { - "color": "dark-green", - "index": 0, - "value": null - }, - { - "color": "dark-yellow", - "index": 1, - "value": 5000000000 - }, - { - "color": "dark-red", - "index": 2, - "value": 7000000000 - } - ], - "values": false - } - }, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 12, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution]))", - "format": "time_series", - "instant": null, - "intervalFactor": 1, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Transmitted", - "type": "gauge", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "columns": [ - { - "text": "Time", - "value": "Time" - }, - { - "text": "Value #A", - "value": "Value #A" - }, - { - "text": "Value #B", - "value": "Value #B" - }, - { - "text": "Value #C", - "value": "Value #C" - }, - { - "text": "Value #D", - "value": "Value #D" - }, - { - "text": "Value #E", - "value": "Value #E" - }, - { - "text": "Value #F", - "value": "Value #F" - }, - { - "text": "pod", - "value": "pod" - } - ], - "datasource": "$datasource", - "fill": 1, - "fontSize": "100%", - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 10 - }, - "id": 5, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null as zero", - "renderer": "flot", - "scroll": true, - "showHeader": true, - "sort": { - "col": 0, - "desc": false - }, - "spaceLength": 10, - "span": 24, - "styles": [ - { - "alias": "Time", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Time", - "thresholds": [ - - ], - "type": "hidden", - "unit": "short" - }, - { - "alias": "Bandwidth Received", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Bandwidth Transmitted", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Rate of Received Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Received Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Pod", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTooltip": "Drill down", - "linkUrl": "d/7a18067ce943a40ae25454675c19ff5c/kubernetes-networking-pod?orgId=1&refresh=30s&var-namespace=$namespace&var-pod=$__cell", - "pattern": "pod", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Status", - "type": "table" - }, - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 19 - }, - "id": 6, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 20 - }, - "id": 7, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 20 - }, - "id": 8, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 29 - }, - "id": 9, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 10, - "w": 12, - "x": 0, - "y": 30 - }, - "id": 10, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 10, - "w": 12, - "x": 12, - "y": 30 - }, - "id": 11, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Packets", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 30 - }, - "id": 12, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 10, - "w": 12, - "x": 0, - "y": 40 - }, - "id": 13, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 10, - "w": 12, - "x": 12, - "y": 40 - }, - "id": 14, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Errors", - "titleSize": "h6", - "type": "row" - } - ], - "refresh": "10s", - "rows": [ - - ], - "schemaVersion": 18, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".+", - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "kube-system", - "value": "kube-system" - }, - "datasource": "$datasource", - "definition": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "resolution", - "options": [ - { - "selected": false, - "text": "30s", - "value": "30s" - }, - { - "selected": true, - "text": "5m", - "value": "5m" - }, - { - "selected": false, - "text": "1h", - "value": "1h" - } - ], - "query": "30s,5m,1h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 2, - "includeAll": false, - "label": null, - "multi": false, - "name": "interval", - "options": [ - { - "selected": true, - "text": "4h", - "value": "4h" - } - ], - "query": "4h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Networking / Namespace (Pods)", - "uid": "8b7a8b326d7a6f1f04244066368c67af", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-workload.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-workload.yaml deleted file mode 100644 index 5abea97774..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-workload.yaml +++ /dev/null @@ -1,1736 +0,0 @@ -{{- /* -Generated from 'namespace-by-workload' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "namespace-by-workload" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - namespace-by-workload.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "panels": [ - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 2, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Current Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 1 - }, - "id": 3, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}} workload {{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Received", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 1 - }, - "id": 4, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}} workload {{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Transmitted", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "columns": [ - { - "text": "Time", - "value": "Time" - }, - { - "text": "Value #A", - "value": "Value #A" - }, - { - "text": "Value #B", - "value": "Value #B" - }, - { - "text": "Value #C", - "value": "Value #C" - }, - { - "text": "Value #D", - "value": "Value #D" - }, - { - "text": "Value #E", - "value": "Value #E" - }, - { - "text": "Value #F", - "value": "Value #F" - }, - { - "text": "Value #G", - "value": "Value #G" - }, - { - "text": "Value #H", - "value": "Value #H" - }, - { - "text": "workload", - "value": "workload" - } - ], - "datasource": "$datasource", - "fill": 1, - "fontSize": "90%", - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 10 - }, - "id": 5, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null as zero", - "renderer": "flot", - "scroll": true, - "showHeader": true, - "sort": { - "col": 0, - "desc": false - }, - "spaceLength": 10, - "span": 24, - "styles": [ - { - "alias": "Time", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Time", - "thresholds": [ - - ], - "type": "hidden", - "unit": "short" - }, - { - "alias": "Current Bandwidth Received", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Current Bandwidth Transmitted", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Average Bandwidth Received", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #C", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Average Bandwidth Transmitted", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #D", - "thresholds": [ - - ], - "type": "number", - "unit": "Bps" - }, - { - "alias": "Rate of Received Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #E", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #F", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Received Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #G", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Rate of Transmitted Packets Dropped", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #H", - "thresholds": [ - - ], - "type": "number", - "unit": "pps" - }, - { - "alias": "Workload", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": true, - "linkTooltip": "Drill down", - "linkUrl": "d/728bf77cc1166d2f3133bf25846876cc/kubernetes-networking-workload?orgId=1&refresh=30s&var-namespace=$namespace&var-type=$type&var-workload=$__cell", - "pattern": "workload", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - } - ], - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - }, - { - "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C", - "step": 10 - }, - { - "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "D", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "E", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "F", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "G", - "step": 10 - }, - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "H", - "step": 10 - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Status", - "type": "table" - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 19 - }, - "id": 6, - "panels": [ - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 20 - }, - "id": 7, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}} workload {{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Rate of Bytes Received", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 20 - }, - "id": 8, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}} workload {{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Rate of Bytes Transmitted", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Average Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 29 - }, - "id": 9, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth HIstory", - "titleSize": "h6", - "type": "row" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 38 - }, - "id": 10, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 38 - }, - "id": 11, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 39 - }, - "id": 12, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 40 - }, - "id": 13, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 40 - }, - "id": 14, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Packets", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 40 - }, - "id": 15, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 41 - }, - "id": 16, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 41 - }, - "id": 17, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}workload{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Errors", - "titleSize": "h6", - "type": "row" - } - ], - "refresh": "10s", - "rows": [ - - ], - "schemaVersion": 18, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "kube-system", - "value": "kube-system" - }, - "datasource": "$datasource", - "definition": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "deployment", - "value": "deployment" - }, - "datasource": "$datasource", - "definition": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\"}, workload_type)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "type", - "options": [ - - ], - "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\"}, workload_type)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "resolution", - "options": [ - { - "selected": false, - "text": "30s", - "value": "30s" - }, - { - "selected": true, - "text": "5m", - "value": "5m" - }, - { - "selected": false, - "text": "1h", - "value": "1h" - } - ], - "query": "30s,5m,1h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 2, - "includeAll": false, - "label": null, - "multi": false, - "name": "interval", - "options": [ - { - "selected": true, - "text": "4h", - "value": "4h" - } - ], - "query": "4h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Networking / Namespace (Workload)", - "uid": "bbb2a765a623ae38130206c7d94a160f", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml deleted file mode 100644 index a4bf29fd11..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml +++ /dev/null @@ -1,1063 +0,0 @@ -{{- /* -Generated from 'node-cluster-rsrc-use' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled (or .Values.nodeExporter.enabled .Values.nodeExporter.forceDeployDashboards) }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "node-cluster-rsrc-use" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - node-cluster-rsrc-use.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 1, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "30s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 2, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "((\n instance:node_cpu_utilisation:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n *\n instance:node_num_cpu:sum{job=\"node-exporter\", cluster=\"$cluster\"}\n) != 0 )\n/ scalar(sum(instance:node_num_cpu:sum{job=\"node-exporter\", cluster=\"$cluster\"}))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}} instance {{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Utilisation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "(\n instance:node_load1_per_cpu:ratio{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance:node_load1_per_cpu:ratio{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Saturation (Load1 per CPU)", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "CPU", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "(\n instance:node_memory_utilisation:ratio{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance:node_memory_utilisation:ratio{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Utilisation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 5, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_vmstat_pgmajfault:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Saturation (Major Page Faults)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "rds", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "rds", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Memory", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - { - "alias": "/Receive/", - "stack": "A" - }, - { - "alias": "/Transmit/", - "stack": "B", - "transform": "negative-Y" - } - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_network_receive_bytes_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Receive", - "refId": "A" - }, - { - "expr": "instance:node_network_transmit_bytes_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Transmit", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Utilisation (Bytes Receive/Transmit)", - "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": null, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 7, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - { - "alias": "/ Receive/", - "stack": "A" - }, - { - "alias": "/ Transmit/", - "stack": "B", - "transform": "negative-Y" - } - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_network_receive_drop_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Receive", - "refId": "A" - }, - { - "expr": "instance:node_network_transmit_drop_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} Transmit", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Saturation (Drops Receive/Transmit)", - "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": null, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Network", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "(\n instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk IO Utilisation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 9, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "(\n instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk IO Saturation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Disk IO", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 10, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum without (device) (\n max without (fstype, mountpoint) ((\n node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"}\n -\n node_filesystem_avail_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"}\n ) != 0)\n)\n/ scalar(sum(max without (fstype, mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"})))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk Space Utilisation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Disk Space", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "node-exporter-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(node_time_seconds, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Node Exporter / USE Method / Cluster", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/node-rsrc-use.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/node-rsrc-use.yaml deleted file mode 100644 index 9c1a8fe59f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/node-rsrc-use.yaml +++ /dev/null @@ -1,1089 +0,0 @@ -{{- /* -Generated from 'node-rsrc-use' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled (or .Values.nodeExporter.enabled .Values.nodeExporter.forceDeployDashboards) }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "node-rsrc-use" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - node-rsrc-use.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 1, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "30s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 2, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_cpu_utilisation:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Utilisation", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Utilisation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_load1_per_cpu:ratio{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Saturation", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Saturation (Load1 per CPU)", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "CPU", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_memory_utilisation:ratio{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Utilisation", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Utilisation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 5, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_vmstat_pgmajfault:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Major page Faults", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Saturation (Major Page Faults)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "rds", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "rds", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Memory", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - { - "alias": "/Receive/", - "stack": "A" - }, - { - "alias": "/Transmit/", - "stack": "B", - "transform": "negative-Y" - } - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_network_receive_bytes_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Receive", - "refId": "A" - }, - { - "expr": "instance:node_network_transmit_bytes_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Transmit", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Utilisation (Bytes Receive/Transmit)", - "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": null, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 7, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - { - "alias": "/ Receive/", - "stack": "A" - }, - { - "alias": "/ Transmit/", - "stack": "B", - "transform": "negative-Y" - } - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance:node_network_receive_drop_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Receive", - "refId": "A" - }, - { - "expr": "instance:node_network_transmit_drop_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Transmit", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Saturation (Drops Receive/Transmit)", - "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": null, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Network", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk IO Utilisation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 9, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk IO Saturation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Disk IO", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, - "gridPos": { - - }, - "id": 10, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(1 -\n (\n max without (mountpoint, fstype) (node_filesystem_avail_bytes{job=\"node-exporter\", fstype!=\"\", instance=\"$instance\", cluster=\"$cluster\"})\n /\n max without (mountpoint, fstype) (node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", instance=\"$instance\", cluster=\"$cluster\"})\n ) != 0\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk Space Utilisation", - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Disk Space", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "node-exporter-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(node_time_seconds, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(node_exporter_build_info{job=\"node-exporter\", cluster=\"$cluster\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Node Exporter / USE Method / Node", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/nodes-darwin.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/nodes-darwin.yaml deleted file mode 100644 index 562802fa07..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/nodes-darwin.yaml +++ /dev/null @@ -1,1073 +0,0 @@ -{{- /* -Generated from 'nodes-darwin' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled (and (or .Values.nodeExporter.enabled .Values.nodeExporter.forceDeployDashboards) .Values.nodeExporter.operatingSystems.darwin.enabled) }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "nodes-darwin" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - nodes-darwin.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 1, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "30s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 2, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "(\n (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode=~\"idle|iowait|steal\", instance=\"$instance\"}[$__rate_interval])))\n/ ignoring(cpu) group_left\n count without (cpu, mode) (node_cpu_seconds_total{job=\"node-exporter\", mode=\"idle\", instance=\"$instance\"})\n)\n", - "format": "time_series", - "intervalFactor": 5, - "legendFormat": "{{`{{`}}cpu{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Usage", - "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": "percentunit", - "label": null, - "logBase": 1, - "max": 1, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 0, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "node_load1{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "1m load average", - "refId": "A" - }, - { - "expr": "node_load5{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "5m load average", - "refId": "B" - }, - { - "expr": "node_load15{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "15m load average", - "refId": "C" - }, - { - "expr": "count(node_cpu_seconds_total{job=\"node-exporter\", instance=\"$instance\", mode=\"idle\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "logical cores", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Load Average", - "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": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "CPU", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 9, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Physical Memory", - "refId": "A" - }, - { - "expr": "(\n node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\"} -\n node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\"} +\n node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\"} +\n node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\"}\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Memory Used", - "refId": "B" - }, - { - "expr": "(\n node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\"} -\n node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\"}\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "App Memory", - "refId": "C" - }, - { - "expr": "node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Wired Memory", - "refId": "D" - }, - { - "expr": "node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Compressed", - "refId": "E" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Usage", - "tooltip": { - "shared": true, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "rgba(50, 172, 45, 0.97)" - }, - { - "color": "rgba(237, 129, 40, 0.89)", - "value": 80 - }, - { - "color": "rgba(245, 54, 54, 0.9)", - "value": 90 - } - ] - }, - "unit": "percent" - } - }, - "gridPos": { - - }, - "id": 5, - "span": 3, - "targets": [ - { - "expr": "(\n (\n avg(node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\"}) -\n avg(node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\"}) +\n avg(node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\"}) +\n avg(node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\"})\n ) /\n avg(node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\"})\n)\n*\n100\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "" - } - ], - "title": "Memory Usage", - "transparent": false, - "type": "gauge" - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Memory", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 0, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - { - "alias": "/ read| written/", - "yaxis": 1 - }, - { - "alias": "/ io time/", - "yaxis": 2 - } - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(node_disk_read_bytes_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}} read", - "refId": "A" - }, - { - "expr": "rate(node_disk_written_bytes_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}} written", - "refId": "B" - }, - { - "expr": "rate(node_disk_io_time_seconds_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}} io time", - "refId": "C" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": { - - }, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "yellow", - "value": 0.8 - }, - { - "color": "red", - "value": 0.9 - } - ] - }, - "unit": "decbytes" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Mounted on" - }, - "properties": [ - { - "id": "custom.width", - "value": 260 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Size" - }, - "properties": [ - { - "id": "custom.width", - "value": 93 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Used" - }, - "properties": [ - { - "id": "custom.width", - "value": 72 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Available" - }, - "properties": [ - { - "id": "custom.width", - "value": 88 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Used, %" - }, - "properties": [ - { - "id": "unit", - "value": "percentunit" - }, - { - "id": "custom.displayMode", - "value": "gradient-gauge" - }, - { - "id": "max", - "value": 1 - }, - { - "id": "min", - "value": 0 - } - ] - } - ] - }, - "gridPos": { - - }, - "id": 7, - "span": 6, - "targets": [ - { - "expr": "max by (mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", instance=\"$instance\", fstype!=\"\", mountpoint!=\"\"})\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "" - }, - { - "expr": "max by (mountpoint) (node_filesystem_avail_bytes{job=\"node-exporter\", instance=\"$instance\", fstype!=\"\", mountpoint!=\"\"})\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "" - } - ], - "title": "Disk Space Usage", - "transformations": [ - { - "id": "groupBy", - "options": { - "fields": { - "Value #A": { - "aggregations": [ - "lastNotNull" - ], - "operation": "aggregate" - }, - "Value #B": { - "aggregations": [ - "lastNotNull" - ], - "operation": "aggregate" - }, - "mountpoint": { - "aggregations": [ - - ], - "operation": "groupby" - } - } - } - }, - { - "id": "merge", - "options": { - - } - }, - { - "id": "calculateField", - "options": { - "alias": "Used", - "binary": { - "left": "Value #A (lastNotNull)", - "operator": "-", - "reducer": "sum", - "right": "Value #B (lastNotNull)" - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "Used, %", - "binary": { - "left": "Used", - "operator": "/", - "reducer": "sum", - "right": "Value #A (lastNotNull)" - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "organize", - "options": { - "excludeByName": { - - }, - "indexByName": { - - }, - "renameByName": { - "Value #A (lastNotNull)": "Size", - "Value #B (lastNotNull)": "Available", - "mountpoint": "Mounted on" - } - } - }, - { - "id": "sortBy", - "options": { - "fields": { - - }, - "sort": [ - { - "field": "Mounted on" - } - ] - } - } - ], - "transparent": false, - "type": "table" - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Disk", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "Network received (bits/s)", - "fill": 0, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(node_network_receive_bytes_total{job=\"node-exporter\", instance=\"$instance\", device!=\"lo\"}[$__rate_interval]) * 8", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Received", - "tooltip": { - "shared": true, - "sort": 0, - "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": "bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "Network transmitted (bits/s)", - "fill": 0, - "fillGradient": 0, - "gridPos": { - - }, - "id": 9, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(node_network_transmit_bytes_total{job=\"node-exporter\", instance=\"$instance\", device!=\"lo\"}[$__rate_interval]) * 8", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Transmitted", - "tooltip": { - "shared": true, - "sort": 0, - "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": "bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Network", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "node-exporter-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": "Instance", - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(node_uname_info{job=\"node-exporter\", sysname=\"Darwin\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 0, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Node Exporter / MacOS", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/nodes.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/nodes.yaml deleted file mode 100644 index 08e567b2f5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/nodes.yaml +++ /dev/null @@ -1,1066 +0,0 @@ -{{- /* -Generated from 'nodes' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled (and (or .Values.nodeExporter.enabled .Values.nodeExporter.forceDeployDashboards) .Values.nodeExporter.operatingSystems.linux.enabled) }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "nodes" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - nodes.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 1, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "30s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 2, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "(\n (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode=~\"idle|iowait|steal\", instance=\"$instance\"}[$__rate_interval])))\n/ ignoring(cpu) group_left\n count without (cpu, mode) (node_cpu_seconds_total{job=\"node-exporter\", mode=\"idle\", instance=\"$instance\"})\n)\n", - "format": "time_series", - "intervalFactor": 5, - "legendFormat": "{{`{{`}}cpu{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU Usage", - "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": "percentunit", - "label": null, - "logBase": 1, - "max": 1, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 0, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "node_load1{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "1m load average", - "refId": "A" - }, - { - "expr": "node_load5{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "5m load average", - "refId": "B" - }, - { - "expr": "node_load15{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "15m load average", - "refId": "C" - }, - { - "expr": "count(node_cpu_seconds_total{job=\"node-exporter\", instance=\"$instance\", mode=\"idle\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "logical cores", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Load Average", - "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": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "CPU", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 9, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "(\n node_memory_MemTotal_bytes{job=\"node-exporter\", instance=\"$instance\"}\n-\n node_memory_MemFree_bytes{job=\"node-exporter\", instance=\"$instance\"}\n-\n node_memory_Buffers_bytes{job=\"node-exporter\", instance=\"$instance\"}\n-\n node_memory_Cached_bytes{job=\"node-exporter\", instance=\"$instance\"}\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "memory used", - "refId": "A" - }, - { - "expr": "node_memory_Buffers_bytes{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "memory buffers", - "refId": "B" - }, - { - "expr": "node_memory_Cached_bytes{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "memory cached", - "refId": "C" - }, - { - "expr": "node_memory_MemFree_bytes{job=\"node-exporter\", instance=\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "memory free", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory Usage", - "tooltip": { - "shared": true, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "rgba(50, 172, 45, 0.97)" - }, - { - "color": "rgba(237, 129, 40, 0.89)", - "value": 80 - }, - { - "color": "rgba(245, 54, 54, 0.9)", - "value": 90 - } - ] - }, - "unit": "percent" - } - }, - "gridPos": { - - }, - "id": 5, - "span": 3, - "targets": [ - { - "expr": "100 -\n(\n avg(node_memory_MemAvailable_bytes{job=\"node-exporter\", instance=\"$instance\"}) /\n avg(node_memory_MemTotal_bytes{job=\"node-exporter\", instance=\"$instance\"})\n* 100\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "" - } - ], - "title": "Memory Usage", - "transparent": false, - "type": "gauge" - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Memory", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 0, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - { - "alias": "/ read| written/", - "yaxis": 1 - }, - { - "alias": "/ io time/", - "yaxis": 2 - } - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(node_disk_read_bytes_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}} read", - "refId": "A" - }, - { - "expr": "rate(node_disk_written_bytes_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}} written", - "refId": "B" - }, - { - "expr": "rate(node_disk_io_time_seconds_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}} io time", - "refId": "C" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk I/O", - "tooltip": { - "shared": true, - "sort": 0, - "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": null, - "show": true - }, - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "datasource": "$datasource", - "fieldConfig": { - "defaults": { - "custom": { - - }, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "yellow", - "value": 0.8 - }, - { - "color": "red", - "value": 0.9 - } - ] - }, - "unit": "decbytes" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Mounted on" - }, - "properties": [ - { - "id": "custom.width", - "value": 260 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Size" - }, - "properties": [ - { - "id": "custom.width", - "value": 93 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Used" - }, - "properties": [ - { - "id": "custom.width", - "value": 72 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Available" - }, - "properties": [ - { - "id": "custom.width", - "value": 88 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Used, %" - }, - "properties": [ - { - "id": "unit", - "value": "percentunit" - }, - { - "id": "custom.displayMode", - "value": "gradient-gauge" - }, - { - "id": "max", - "value": 1 - }, - { - "id": "min", - "value": 0 - } - ] - } - ] - }, - "gridPos": { - - }, - "id": 7, - "span": 6, - "targets": [ - { - "expr": "max by (mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", instance=\"$instance\", fstype!=\"\", mountpoint!=\"\"})\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "" - }, - { - "expr": "max by (mountpoint) (node_filesystem_avail_bytes{job=\"node-exporter\", instance=\"$instance\", fstype!=\"\", mountpoint!=\"\"})\n", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "" - } - ], - "title": "Disk Space Usage", - "transformations": [ - { - "id": "groupBy", - "options": { - "fields": { - "Value #A": { - "aggregations": [ - "lastNotNull" - ], - "operation": "aggregate" - }, - "Value #B": { - "aggregations": [ - "lastNotNull" - ], - "operation": "aggregate" - }, - "mountpoint": { - "aggregations": [ - - ], - "operation": "groupby" - } - } - } - }, - { - "id": "merge", - "options": { - - } - }, - { - "id": "calculateField", - "options": { - "alias": "Used", - "binary": { - "left": "Value #A (lastNotNull)", - "operator": "-", - "reducer": "sum", - "right": "Value #B (lastNotNull)" - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "Used, %", - "binary": { - "left": "Used", - "operator": "/", - "reducer": "sum", - "right": "Value #A (lastNotNull)" - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "organize", - "options": { - "excludeByName": { - - }, - "indexByName": { - - }, - "renameByName": { - "Value #A (lastNotNull)": "Size", - "Value #B (lastNotNull)": "Available", - "mountpoint": "Mounted on" - } - } - }, - { - "id": "sortBy", - "options": { - "fields": { - - }, - "sort": [ - { - "field": "Mounted on" - } - ] - } - } - ], - "transparent": false, - "type": "table" - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Disk", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "Network received (bits/s)", - "fill": 0, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(node_network_receive_bytes_total{job=\"node-exporter\", instance=\"$instance\", device!=\"lo\"}[$__rate_interval]) * 8", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Received", - "tooltip": { - "shared": true, - "sort": 0, - "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": "bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "description": "Network transmitted (bits/s)", - "fill": 0, - "fillGradient": 0, - "gridPos": { - - }, - "id": 9, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(node_network_transmit_bytes_total{job=\"node-exporter\", instance=\"$instance\", device!=\"lo\"}[$__rate_interval]) * 8", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}device{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Transmitted", - "tooltip": { - "shared": true, - "sort": 0, - "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": "bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Network", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "node-exporter-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": "Instance", - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(node_uname_info{job=\"node-exporter\", sysname!=\"Darwin\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 0, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Node Exporter / Nodes", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml deleted file mode 100644 index 0e12e0a7bb..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml +++ /dev/null @@ -1,587 +0,0 @@ -{{- /* -Generated from 'persistentvolumesusage' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "persistentvolumesusage" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - persistentvolumesusage.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 9, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "(\n sum without(instance, node) (topk(1, (kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n -\n sum without(instance, node) (topk(1, (kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n)\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "Used Space", - "refId": "A" - }, - { - "expr": "sum without(instance, node) (topk(1, (kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "Free Space", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Volume Space Usage", - "tooltip": { - "shared": false, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "$datasource", - "format": "percent", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": true, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - - }, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "rightSide": true - }, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 3, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "max without(instance,node) (\n(\n topk(1, kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n -\n topk(1, kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n)\n/\ntopk(1, kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n* 100)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "80, 90", - "title": "Volume Space Usage", - "tooltip": { - "shared": false - }, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 9, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "Used inodes", - "refId": "A" - }, - { - "expr": "(\n sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n -\n sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n)\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": " Free inodes", - "refId": "B" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Volume inodes Usage", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "none", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "none", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(50, 172, 45, 0.97)", - "rgba(237, 129, 40, 0.89)", - "rgba(245, 54, 54, 0.9)" - ], - "datasource": "$datasource", - "format": "percent", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": true, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - - }, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "rightSide": true - }, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 3, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "max without(instance,node) (\ntopk(1, kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n/\ntopk(1, kubelet_volume_stats_inodes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n* 100)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "80, 90", - "title": "Volume inodes Usage", - "tooltip": { - "shared": false - }, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": "cluster", - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(kubelet_volume_stats_capacity_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": "Namespace", - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\"}, namespace)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": "PersistentVolumeClaim", - "multi": false, - "name": "volume", - "options": [ - - ], - "query": "label_values(kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\"}, persistentvolumeclaim)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-7d", - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Persistent Volumes", - "uid": "919b92a8e8041bd567af9edab12c840c", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/pod-total.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/pod-total.yaml deleted file mode 100644 index b174822a5a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/pod-total.yaml +++ /dev/null @@ -1,1228 +0,0 @@ -{{- /* -Generated from 'pod-total' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "pod-total" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - pod-total.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "panels": [ - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 2, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Current Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "decimals": 0, - "format": "time_series", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 1 - }, - "height": 9, - "id": 3, - "interval": null, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "minSpan": 12, - "nullPointMode": "connected", - "nullText": null, - "options": { - "fieldOptions": { - "calcs": [ - "last" - ], - "defaults": { - "max": 10000000000, - "min": 0, - "title": "$namespace: $pod", - "unit": "Bps" - }, - "mappings": [ - - ], - "override": { - - }, - "thresholds": [ - { - "color": "dark-green", - "index": 0, - "value": null - }, - { - "color": "dark-yellow", - "index": 1, - "value": 5000000000 - }, - { - "color": "dark-red", - "index": 2, - "value": 7000000000 - } - ], - "values": false - } - }, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 12, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution]))", - "format": "time_series", - "instant": null, - "intervalFactor": 1, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Received", - "type": "gauge", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "decimals": 0, - "format": "time_series", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 1 - }, - "height": 9, - "id": 4, - "interval": null, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "minSpan": 12, - "nullPointMode": "connected", - "nullText": null, - "options": { - "fieldOptions": { - "calcs": [ - "last" - ], - "defaults": { - "max": 10000000000, - "min": 0, - "title": "$namespace: $pod", - "unit": "Bps" - }, - "mappings": [ - - ], - "override": { - - }, - "thresholds": [ - { - "color": "dark-green", - "index": 0, - "value": null - }, - { - "color": "dark-yellow", - "index": 1, - "value": 5000000000 - }, - { - "color": "dark-red", - "index": 2, - "value": 7000000000 - } - ], - "values": false - } - }, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 12, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution]))", - "format": "time_series", - "instant": null, - "intervalFactor": 1, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Transmitted", - "type": "gauge", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 10 - }, - "id": 5, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 11 - }, - "id": 6, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 11 - }, - "id": 7, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 20 - }, - "id": 8, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 10, - "w": 12, - "x": 0, - "y": 21 - }, - "id": 9, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 10, - "w": 12, - "x": 12, - "y": 21 - }, - "id": 10, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Packets", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 21 - }, - "id": 11, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 10, - "w": 12, - "x": 0, - "y": 32 - }, - "id": 12, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 10, - "w": 12, - "x": 12, - "y": 32 - }, - "id": 13, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Errors", - "titleSize": "h6", - "type": "row" - } - ], - "refresh": "10s", - "rows": [ - - ], - "schemaVersion": 18, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".+", - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "kube-system", - "value": "kube-system" - }, - "datasource": "$datasource", - "definition": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".+", - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "definition": "label_values(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}, pod)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "pod", - "options": [ - - ], - "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}, pod)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "resolution", - "options": [ - { - "selected": false, - "text": "30s", - "value": "30s" - }, - { - "selected": true, - "text": "5m", - "value": "5m" - }, - { - "selected": false, - "text": "1h", - "value": "1h" - } - ], - "query": "30s,5m,1h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 2, - "includeAll": false, - "label": null, - "multi": false, - "name": "interval", - "options": [ - { - "selected": true, - "text": "4h", - "value": "4h" - } - ], - "query": "4h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Networking / Pod", - "uid": "7a18067ce943a40ae25454675c19ff5c", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml deleted file mode 100644 index 5fc57e1b28..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml +++ /dev/null @@ -1,1674 +0,0 @@ -{{- /* -Generated from 'prometheus-remote-write' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.prometheus.prometheusSpec.remoteWriteDashboards }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "prometheus-remote-write" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - prometheus-remote-write.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "60s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 2, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "(\n prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~\"$cluster\", instance=~\"$instance\"} \n- \n ignoring(remote_name, url) group_right(instance) (prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~\"$cluster\", instance=~\"$instance\"} != 0)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Highest Timestamp In vs. Highest Timestamp Sent", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "clamp_min(\n rate(prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) \n- \n ignoring (remote_name, url) group_right(instance) rate(prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])\n, 0)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate[5m]", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Timestamps", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(\n prometheus_remote_storage_samples_in_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])\n- \n ignoring(remote_name, url) group_right(instance) (rate(prometheus_remote_storage_succeeded_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]))\n- \n (rate(prometheus_remote_storage_dropped_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_dropped_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]))\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate, in vs. succeeded or dropped [5m]", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Samples", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 5, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "minSpan": 6, - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_remote_storage_shards{cluster=~\"$cluster\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Shards", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_remote_storage_shards_max{cluster=~\"$cluster\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Max Shards", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 7, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_remote_storage_shards_min{cluster=~\"$cluster\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Min Shards", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_remote_storage_shards_desired{cluster=~\"$cluster\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Desired Shards", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Shards", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 9, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_remote_storage_shard_capacity{cluster=~\"$cluster\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Shard Capacity", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 10, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_remote_storage_pending_samples{cluster=~\"$cluster\", instance=~\"$instance\"} or prometheus_remote_storage_samples_pending{cluster=~\"$cluster\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Pending Samples", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Shard Details", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 11, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_tsdb_wal_segment_current{cluster=~\"$cluster\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "TSDB Current Segment", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "none", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 12, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_wal_watcher_current_segment{cluster=~\"$cluster\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}consumer{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Remote Write Current Segment", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "none", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Segments", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 13, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(prometheus_remote_storage_dropped_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_dropped_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Dropped Samples", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 14, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(prometheus_remote_storage_failed_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Failed Samples", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 15, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(prometheus_remote_storage_retried_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_retried_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Retried Samples", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 16, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 3, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(prometheus_remote_storage_enqueue_retries_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Enqueue Retries", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Misc. Rates", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "prometheus-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - "text": { - "selected": true, - "text": "All", - "value": "$__all" - }, - "value": { - "selected": true, - "text": "All", - "value": "$__all" - } - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": true, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(kube_pod_container_info{image=~\".*prometheus.*\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - "text": { - "selected": true, - "text": "All", - "value": "$__all" - }, - "value": { - "selected": true, - "text": "All", - "value": "$__all" - } - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(prometheus_build_info{cluster=~\"$cluster\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "url", - "options": [ - - ], - "query": "label_values(prometheus_remote_storage_shards{cluster=~\"$cluster\", instance=~\"$instance\"}, url)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-6h", - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Prometheus / Remote Write", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/prometheus.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/prometheus.yaml deleted file mode 100644 index b1f9d73332..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/prometheus.yaml +++ /dev/null @@ -1,1235 +0,0 @@ -{{- /* -Generated from 'prometheus' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "prometheus" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - prometheus.json: |- - { - "annotations": { - "list": [ - - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "links": [ - - ], - "refresh": "60s", - "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": 12, - "stack": false, - "steppedLine": false, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Count", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #A", - "thresholds": [ - - ], - "type": "hidden", - "unit": "short" - }, - { - "alias": "Uptime", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "Value #B", - "thresholds": [ - - ], - "type": "number", - "unit": "s" - }, - { - "alias": "Instance", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "instance", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Job", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "job", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "Version", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "link": false, - "linkTargetBlank": false, - "linkTooltip": "Drill down", - "linkUrl": "", - "pattern": "version", - "thresholds": [ - - ], - "type": "number", - "unit": "short" - }, - { - "alias": "", - "colorMode": null, - "colors": [ - - ], - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "decimals": 2, - "pattern": "/.*/", - "thresholds": [ - - ], - "type": "string", - "unit": "short" - } - ], - "targets": [ - { - "expr": "count by (job, instance, version) (prometheus_build_info{job=~\"$job\", instance=~\"$instance\"})", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 10 - }, - { - "expr": "max by (job, instance) (time() - process_start_time_seconds{job=~\"$job\", instance=~\"$instance\"})", - "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Prometheus Stats", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "transform": "table", - "type": "table", - "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": "Prometheus Stats", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "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(rate(prometheus_target_sync_length_seconds_sum{job=~\"$job\",instance=~\"$instance\"}[5m])) by (scrape_job) * 1e3", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}scrape_job{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Target Sync", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "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(prometheus_sd_discovered_targets{job=~\"$job\",instance=~\"$instance\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Targets", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Targets", - "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": "Discovery", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "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": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(prometheus_target_interval_length_seconds_sum{job=~\"$job\",instance=~\"$instance\"}[5m]) / rate(prometheus_target_interval_length_seconds_count{job=~\"$job\",instance=~\"$instance\"}[5m]) * 1e3", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}interval{{`}}`}} configured", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Scrape Interval Duration", - "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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "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": 4, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (job) (rate(prometheus_target_scrapes_exceeded_body_size_limit_total[1m]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "exceeded body size limit: {{`{{`}}job{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum by (job) (rate(prometheus_target_scrapes_exceeded_sample_limit_total[1m]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "exceeded sample limit: {{`{{`}}job{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum by (job) (rate(prometheus_target_scrapes_sample_duplicate_timestamp_total[1m]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "duplicate timestamp: {{`{{`}}job{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum by (job) (rate(prometheus_target_scrapes_sample_out_of_bounds_total[1m]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "out of bounds: {{`{{`}}job{{`}}`}}", - "legendLink": null, - "step": 10 - }, - { - "expr": "sum by (job) (rate(prometheus_target_scrapes_sample_out_of_order_total[1m]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "out of order: {{`{{`}}job{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Scrape failures", - "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": 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": 4, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "rate(prometheus_tsdb_head_samples_appended_total{job=~\"$job\",instance=~\"$instance\"}[5m])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}job{{`}}`}} {{`{{`}}instance{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Appended Samples", - "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": "Retrieval", - "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": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "prometheus_tsdb_head_series{job=~\"$job\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}job{{`}}`}} {{`{{`}}instance{{`}}`}} head series", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Head 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": 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": "prometheus_tsdb_head_chunks{job=~\"$job\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}job{{`}}`}} {{`{{`}}instance{{`}}`}} head chunks", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Head Chunks", - "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": "Storage", - "titleSize": "h6" - }, - { - "collapse": false, - "height": "250px", - "panels": [ - { - "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": 6, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "rate(prometheus_engine_query_duration_seconds_count{job=~\"$job\",instance=~\"$instance\",slice=\"inner_eval\"}[5m])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}job{{`}}`}} {{`{{`}}instance{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Query 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 - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "id": 10, - "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": "max by (slice) (prometheus_engine_query_duration_seconds{quantile=\"0.9\",job=~\"$job\",instance=~\"$instance\"}) * 1e3", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}slice{{`}}`}}", - "legendLink": null, - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Stage Duration", - "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": "Query", - "titleSize": "h6" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "prometheus-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": ".+", - "current": { - "selected": true, - "text": "All", - "value": "$__all" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": "job", - "multi": true, - "name": "job", - "options": [ - - ], - "query": "label_values(prometheus_build_info{job=\"prometheus-k8s\",namespace=\"monitoring\"}, job)", - "refresh": 1, - "regex": "", - "sort": 2, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".+", - "current": { - "selected": true, - "text": "All", - "value": "$__all" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": "instance", - "multi": true, - "name": "instance", - "options": [ - - ], - "query": "label_values(prometheus_build_info{job=~\"$job\"}, instance)", - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Prometheus / Overview", - "uid": "", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/proxy.yaml deleted file mode 100644 index 69b8abcd60..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/proxy.yaml +++ /dev/null @@ -1,1276 +0,0 @@ -{{- /* -Generated from 'proxy' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -{{- if (include "exporter.kubeProxy.enabled" .)}} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "proxy" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - proxy.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - - }, - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "rightSide": true - }, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 2, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - {{- if .Values.k3sServer.enabled }} - "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", metrics_path=\"/metrics\"})", - {{- else }} - "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\"})", - {{- end }} - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "title": "Up", - "tooltip": { - "shared": false - }, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "min" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 5, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(kubeproxy_sync_proxy_rules_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "rate", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rules Sync Rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 5, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99,rate(kubeproxy_sync_proxy_rules_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rule Sync Latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(kubeproxy_network_programming_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "rate", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Programming Rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 6, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(kubeproxy_network_programming_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Programming Latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "2xx", - "refId": "A" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "3xx", - "refId": "B" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "4xx", - "refId": "C" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "5xx", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Kube API Request Rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 8, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\",instance=~\"$instance\",verb=\"POST\"}[$__rate_interval])) by (verb, url, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Post Request Latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 9, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, url, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Get Request Latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory", - "tooltip": { - "shared": false, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 11, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU usage", - "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": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 12, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "go_goroutines{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Goroutines", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": "cluster", - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubeProxy.jobName" . }}\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubeProxy.jobName" . }}\", cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Proxy", - "uid": "632e265de029684c40b21cb76bca4f94", - "version": 0 - } -{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/scheduler.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/scheduler.yaml deleted file mode 100644 index 4d439c8980..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/scheduler.yaml +++ /dev/null @@ -1,1118 +0,0 @@ -{{- /* -Generated from 'scheduler' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -{{- if (include "exporter.kubeScheduler.enabled" .)}} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "scheduler" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - scheduler.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - - ] - }, - "editable": false, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "refresh": "10s", - "rows": [ - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "datasource": "$datasource", - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - - }, - "id": 2, - "interval": "1m", - "legend": { - "alignAsTable": true, - "rightSide": true - }, - "links": [ - - ], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "span": 2, - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "", - "targets": [ - { - {{- if .Values.k3sServer.enabled }} - "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", metrics_path=\"/metrics\"})", - {{- else }} - "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\"})", - {{- end }} - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "", - "title": "Up", - "tooltip": { - "shared": false - }, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "min" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 3, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 5, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(scheduler_e2e_scheduling_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} e2e", - "refId": "A" - }, - { - "expr": "sum(rate(scheduler_binding_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} binding", - "refId": "B" - }, - { - "expr": "sum(rate(scheduler_scheduling_algorithm_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} scheduling algorithm", - "refId": "C" - }, - { - "expr": "sum(rate(scheduler_volume_scheduling_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} volume", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Scheduling Rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 4, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 5, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} e2e", - "refId": "A" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(scheduler_binding_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} binding", - "refId": "B" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} scheduling algorithm", - "refId": "C" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(scheduler_volume_scheduling_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} volume", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Scheduling latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 5, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "2xx", - "refId": "A" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "3xx", - "refId": "B" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "4xx", - "refId": "C" - }, - { - "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "5xx", - "refId": "D" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Kube API Request Rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 6, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 8, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\", verb=\"POST\"}[$__rate_interval])) by (verb, url, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Post Request Latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 7, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, url, le))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Get Request Latency 99th Quantile", - "tooltip": { - "shared": false, - "sort": 0, - "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": "s", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 8, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Memory", - "tooltip": { - "shared": false, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 9, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "CPU usage", - "tooltip": { - "shared": false, - "sort": 0, - "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": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, - "gridPos": { - - }, - "id": 10, - "interval": "1m", - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [ - - ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 4, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "go_goroutines{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{`{{`}}instance{{`}}`}}", - "refId": "A" - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Goroutines", - "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 - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": false, - "title": "Dashboard Row", - "titleSize": "h6", - "type": "row" - } - ], - "schemaVersion": 14, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": "cluster", - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubeScheduler.jobName" . }}\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "instance", - "options": [ - - ], - "query": "label_values(up{job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", cluster=\"$cluster\"}, instance)", - "refresh": 2, - "regex": "", - "sort": 1, - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Scheduler", - "uid": "2e6b6a3b4bddf1427b3a55aa1311c656", - "version": 0 - } -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/workload-total.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/workload-total.yaml deleted file mode 100644 index 8784c7116c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/dashboards-1.14/workload-total.yaml +++ /dev/null @@ -1,1438 +0,0 @@ -{{- /* -Generated from 'workload-total' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "workload-total" | trunc 63 | trimSuffix "-" }} - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: - workload-total.json: |- - { - "__inputs": [ - - ], - "__requires": [ - - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ - - ], - "panels": [ - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 2, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Current Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 1 - }, - "id": 3, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}} pod {{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Received", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 1 - }, - "id": 4, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}} pod {{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Current Rate of Bytes Transmitted", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 10 - }, - "id": 5, - "panels": [ - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 11 - }, - "id": 6, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}} pod {{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Rate of Bytes Received", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": true, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 11 - }, - "id": 7, - "legend": { - "alignAsTable": true, - "avg": false, - "current": true, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "current", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": false, - "linewidth": 1, - "links": [ - - ], - "minSpan": 24, - "nullPointMode": "null", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 24, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}} pod {{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Average Rate of Bytes Transmitted", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "series", - "name": null, - "show": false, - "values": [ - "current" - ] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Average Bandwidth", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": false, - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 11 - }, - "id": 8, - "panels": [ - - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Bandwidth HIstory", - "titleSize": "h6", - "type": "row" - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 12 - }, - "id": 9, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Receive Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 12 - }, - "id": 10, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Transmit Bandwidth", - "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": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 21 - }, - "id": 11, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 22 - }, - "id": 12, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 22 - }, - "id": 13, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Packets", - "titleSize": "h6", - "type": "row" - }, - { - "collapse": true, - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 22 - }, - "id": 14, - "panels": [ - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 23 - }, - "id": 15, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Received Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - }, - { - "aliasColors": { - - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 2, - "fillGradient": 0, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 23 - }, - "id": 16, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sideWidth": null, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [ - - ], - "minSpan": 12, - "nullPointMode": "connected", - "paceLength": 10, - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ - - ], - "spaceLength": 10, - "span": 12, - "stack": true, - "steppedLine": false, - "targets": [ - { - "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{`{{`}}pod{{`}}`}}", - "refId": "A", - "step": 10 - } - ], - "thresholds": [ - - ], - "timeFrom": null, - "timeShift": null, - "title": "Rate of Transmitted Packets Dropped", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ - - ] - }, - "yaxes": [ - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "pps", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - } - ] - } - ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, - "title": "Errors", - "titleSize": "h6", - "type": "row" - } - ], - "refresh": "10s", - "rows": [ - - ], - "schemaVersion": 18, - "style": "dark", - "tags": [ - "kubernetes-mixin" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Data Source", - "name": "datasource", - "options": [ - - ], - "query": "prometheus", - "refresh": 1, - "regex": "", - "type": "datasource" - }, - { - "allValue": null, - "current": { - - }, - "datasource": "$datasource", - "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, - "includeAll": false, - "label": null, - "multi": false, - "name": "cluster", - "options": [ - - ], - "query": "label_values(kube_pod_info{job=\"kube-state-metrics\"}, cluster)", - "refresh": 2, - "regex": "", - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".+", - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "kube-system", - "value": "kube-system" - }, - "datasource": "$datasource", - "definition": "label_values(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\"}, namespace)", - "hide": 0, - "includeAll": true, - "label": null, - "multi": false, - "name": "namespace", - "options": [ - - ], - "query": "label_values(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\"}, namespace)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "", - "value": "" - }, - "datasource": "$datasource", - "definition": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\"}, workload)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "workload", - "options": [ - - ], - "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\"}, workload)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "deployment", - "value": "deployment" - }, - "datasource": "$datasource", - "definition": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\"}, workload_type)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "type", - "options": [ - - ], - "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\"}, workload_type)", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 0, - "includeAll": false, - "label": null, - "multi": false, - "name": "resolution", - "options": [ - { - "selected": false, - "text": "30s", - "value": "30s" - }, - { - "selected": true, - "text": "5m", - "value": "5m" - }, - { - "selected": false, - "text": "1h", - "value": "1h" - } - ], - "query": "30s,5m,1h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "useTags": false - }, - { - "allValue": null, - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "5m", - "value": "5m" - }, - "datasource": "$datasource", - "hide": 2, - "includeAll": false, - "label": null, - "multi": false, - "name": "interval", - "options": [ - { - "selected": true, - "text": "4h", - "value": "4h" - } - ], - "query": "4h", - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [ - - ], - "tagsQuery": "", - "type": "interval", - "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", - "title": "Kubernetes / Networking / Workload", - "uid": "728bf77cc1166d2f3133bf25846876cc", - "version": 0 - } -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/namespaces.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/namespaces.yaml deleted file mode 100644 index 39ed210ed4..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/grafana/namespaces.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled (not .Values.grafana.defaultDashboards.useExistingNamespace) }} -apiVersion: v1 -kind: Namespace -metadata: - name: {{ .Values.grafana.defaultDashboards.namespace }} - labels: - name: {{ .Values.grafana.defaultDashboards.namespace }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - annotations: -{{- if not .Values.grafana.defaultDashboards.cleanupOnUninstall }} - helm.sh/resource-policy: "keep" -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/_prometheus-operator.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/_prometheus-operator.tpl deleted file mode 100644 index 6ae9dc72e6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/_prometheus-operator.tpl +++ /dev/null @@ -1,7 +0,0 @@ -{{/* Generate basic labels for prometheus-operator */}} -{{- define "kube-prometheus-stack.prometheus-operator.labels" }} -{{- include "kube-prometheus-stack.labels" . }} -app: {{ template "kube-prometheus-stack.name" . }}-operator -app.kubernetes.io/name: {{ template "kube-prometheus-stack.name" . }}-prometheus-operator -app.kubernetes.io/component: prometheus-operator -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl deleted file mode 100644 index f419caf54b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl +++ /dev/null @@ -1,6 +0,0 @@ -{{/* Generate basic labels for prometheus-operator-webhook */}} -{{- define "kube-prometheus-stack.prometheus-operator-webhook.labels" }} -{{- include "kube-prometheus-stack.labels" . }} -app.kubernetes.io/name: {{ template "kube-prometheus-stack.name" . }}-prometheus-operator -app.kubernetes.io/component: prometheus-operator-webhook -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml deleted file mode 100644 index 054eac4a77..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml +++ /dev/null @@ -1,143 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.deployment.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }}-webhook - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 4 }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.labels }} -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.labels | indent 4 }} -{{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.annotations }} - annotations: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.annotations | indent 4 }} -{{- end }} -spec: - replicas: {{ .Values.prometheusOperator.admissionWebhooks.deployment.replicas }} - revisionHistoryLimit: {{ .Values.prometheusOperator.admissionWebhooks.deployment.revisionHistoryLimit }} - {{- with .Values.prometheusOperator.admissionWebhooks.deployment.strategy }} - strategy: - {{- toYaml . | nindent 4 }} - {{- end }} - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook - release: {{ $.Release.Name | quote }} - template: - metadata: - labels: - app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 8 }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.podLabels }} -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.podLabels | indent 8 }} -{{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.podAnnotations }} - annotations: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.podAnnotations | indent 8 }} -{{- end }} - spec: - {{- if .Values.prometheusOperator.admissionWebhooks.deployment.priorityClassName }} - priorityClassName: {{ .Values.prometheusOperator.admissionWebhooks.deployment.priorityClassName }} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- include "kube-prometheus-stack.imagePullSecrets" . | indent 8 }} - {{- end }} - containers: - - name: prometheus-operator-admission-webhook - {{- $operatorRegistry := .Values.global.imageRegistry | default .Values.prometheusOperator.admissionWebhooks.deployment.image.registry -}} - {{- if .Values.prometheusOperator.admissionWebhooks.deployment.image.sha }} - image: "{{ $operatorRegistry }}/{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.sha }}" - {{- else }} - image: "{{ $operatorRegistry }}/{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.tag | default .Chart.AppVersion }}" - {{- end }} - imagePullPolicy: "{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.pullPolicy }}" - args: - {{- if .Values.prometheusOperator.admissionWebhooks.deployment.logFormat }} - - --log-format={{ .Values.prometheusOperator.admissionWebhooks.deployment.logFormat }} - {{- end }} - {{- if .Values.prometheusOperator.admissionWebhooks.deployment.logLevel }} - - --log-level={{ .Values.prometheusOperator.admissionWebhooks.deployment.logLevel }} - {{- end }} - {{- if .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled }} - - "--web.enable-tls=true" - - "--web.cert-file=/cert/{{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}tls.crt{{ else }}cert{{ end }}" - - "--web.key-file=/cert/{{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}tls.key{{ else }}key{{ end }}" - - "--web.listen-address=:{{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.internalPort }}" - - "--web.tls-min-version={{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.tlsMinVersion }}" - ports: - - containerPort: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.internalPort }} - name: https - {{- else }} - ports: - - containerPort: 8080 - name: http - {{- end }} - {{- if .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: /healthz - port: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled | ternary "https" "http" }} - scheme: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled | ternary "HTTPS" "HTTP" }} - initialDelaySeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.failureThreshold }} - {{- end }} - {{- if .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: /healthz - port: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled | ternary "https" "http" }} - scheme: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled | ternary "HTTPS" "HTTP" }} - initialDelaySeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.failureThreshold }} - {{- end }} - resources: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.resources | indent 12 }} - securityContext: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.containerSecurityContext | indent 12 }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled }} - volumeMounts: - - name: tls-secret - mountPath: /cert - readOnly: true - volumes: - - name: tls-secret - secret: - defaultMode: 420 - secretName: {{ template "kube-prometheus-stack.fullname" . }}-admission -{{- end }} - {{- with .Values.prometheusOperator.admissionWebhooks.deployment.dnsConfig }} - dnsConfig: -{{ toYaml . | indent 8 }} - {{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.securityContext }} - securityContext: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.securityContext | indent 8 }} -{{- end }} - serviceAccountName: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }}-webhook - automountServiceAccountToken: {{ .Values.prometheusOperator.admissionWebhooks.deployment.automountServiceAccountToken }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.hostNetwork }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet -{{- end }} - {{- with .Values.prometheusOperator.admissionWebhooks.deployment.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.prometheusOperator.admissionWebhooks.deployment.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.prometheusOperator.admissionWebhooks.deployment.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml deleted file mode 100644 index 04458b9675..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.podDisruptionBudget -}} -apiVersion: {{ include "kube-prometheus-stack.pdb.apiVersion" . }} -kind: PodDisruptionBudget -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }}-webhook - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 4 }} -spec: - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook - release: {{ $.Release.Name | quote }} -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.podDisruptionBudget | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/service.yaml deleted file mode 100644 index 6de9cbb71d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/service.yaml +++ /dev/null @@ -1,62 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.deployment.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }}-webhook - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 4 }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.labels }} -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.service.labels | indent 4 }} -{{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.annotations }} - annotations: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.service.annotations | indent 4 }} -{{- end }} -spec: -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.clusterIP }} - clusterIP: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.clusterIP }} -{{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.ipDualStack.ipFamilyPolicy }} -{{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.externalIPs }} - externalIPs: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.loadBalancerIP }} -{{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.prometheusOperator.admissionWebhooks.deployment.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} -{{- if ne .Values.prometheusOperator.admissionWebhooks.deployment.service.type "ClusterIP" }} - externalTrafficPolicy: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.externalTrafficPolicy }} -{{- end }} - ports: - {{- if not .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled }} - - name: http - {{- if eq .Values.prometheusOperator.admissionWebhooks.deployment.service.type "NodePort" }} - nodePort: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.nodePort }} - {{- end }} - port: 8080 - targetPort: http - {{- end }} - {{- if .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled }} - - name: https - {{- if eq .Values.prometheusOperator.admissionWebhooks.deployment.service.type "NodePort"}} - nodePort: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.nodePortTls }} - {{- end }} - port: 443 - targetPort: https - {{- end }} - selector: - app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook - release: {{ $.Release.Name | quote }} - type: "{{ .Values.prometheusOperator.admissionWebhooks.deployment.service.type }}" -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml deleted file mode 100644 index 55511da36b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.deployment.enabled }} -apiVersion: v1 -kind: ServiceAccount -automountServiceAccountToken: {{ .Values.prometheusOperator.admissionWebhooks.deployment.serviceAccount.automountServiceAccountToken }} -metadata: - name: {{ template "kube-prometheus-stack.operator.admissionWebhooks.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-operator - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | indent 4 }} -{{- if .Values.global.imagePullSecrets }} -imagePullSecrets: -{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml deleted file mode 100644 index f7543b0f1a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml +++ /dev/null @@ -1,36 +0,0 @@ -{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "cilium") }} -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: cilium.io/v2 -kind: CiliumNetworkPolicy -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission-create - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - helm.sh/hook: pre-install,pre-upgrade - helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded - ## Ensure this is run before the job - helm.sh/hook-weight: "-5" - {{- with .Values.prometheusOperator.admissionWebhooks.annotations }} - {{ toYaml . | nindent 4 }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-create - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -spec: - endpointSelector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-create - {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} - {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} - {{- else }} - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 6 }} - {{- end }} - egress: - {{- if and .Values.prometheusOperator.networkPolicy.cilium .Values.prometheusOperator.networkPolicy.cilium.egress }} - {{ toYaml .Values.prometheusOperator.networkPolicy.cilium.egress | nindent 6 }} - {{- else }} - - toEntities: - - kube-apiserver - {{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml deleted file mode 100644 index 4e3b0d9225..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml +++ /dev/null @@ -1,36 +0,0 @@ -{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "cilium") }} -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: cilium.io/v2 -kind: CiliumNetworkPolicy -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission-patch - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - helm.sh/hook: post-install,post-upgrade - helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded - ## Ensure this is run before the job - helm.sh/hook-weight: "-5" - {{- with .Values.prometheusOperator.admissionWebhooks.patch.annotations }} - {{ toYaml . | nindent 4 }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -spec: - endpointSelector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch - {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} - {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} - {{- else }} - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 6 }} - {{- end }} - egress: - {{- if and .Values.prometheusOperator.networkPolicy.cilium .Values.prometheusOperator.networkPolicy.cilium.egress }} - {{ toYaml .Values.prometheusOperator.networkPolicy.cilium.egress | nindent 6 }} - {{- else }} - - toEntities: - - kube-apiserver - {{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml deleted file mode 100644 index 1695490354..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - annotations: - "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -rules: - - apiGroups: - - admissionregistration.k8s.io - resources: - - validatingwebhookconfigurations - - mutatingwebhookconfigurations - verbs: - - get - - update -{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.global.rbac.pspEnabled }} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} - - apiGroups: ['policy'] -{{- else }} - - apiGroups: ['extensions'] -{{- end }} - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "kube-prometheus-stack.fullname" . }}-admission -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml deleted file mode 100644 index 4cf1335b22..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - annotations: - "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "kube-prometheus-stack.fullname" . }}-admission -subjects: - - kind: ServiceAccount - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml deleted file mode 100644 index baed83db48..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml +++ /dev/null @@ -1,73 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission-create - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": pre-install,pre-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded -{{- with .Values.prometheusOperator.admissionWebhooks.annotations }} -{{ toYaml . | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-create - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -spec: - {{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }} - # Alpha feature since k8s 1.12 - ttlSecondsAfterFinished: 0 - {{- end }} - template: - metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission-create -{{- with .Values.prometheusOperator.admissionWebhooks.patch.podAnnotations }} - annotations: -{{ toYaml . | indent 8 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-create - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 8 }} - spec: - {{- if .Values.prometheusOperator.admissionWebhooks.patch.priorityClassName }} - priorityClassName: {{ .Values.prometheusOperator.admissionWebhooks.patch.priorityClassName }} - {{- end }} - containers: - - name: create - {{- $registry := include "monitoring_registry" . | default .Values.prometheusOperator.admissionWebhooks.patch.image.registry -}} - {{- if .Values.prometheusOperator.admissionWebhooks.patch.image.sha }} - image: {{ $registry }}/{{ .Values.prometheusOperator.admissionWebhooks.patch.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.tag }}@sha256:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.sha }} - {{- else }} - image: {{ $registry }}/{{ .Values.prometheusOperator.admissionWebhooks.patch.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.tag }} - {{- end }} - imagePullPolicy: {{ .Values.prometheusOperator.admissionWebhooks.patch.image.pullPolicy }} - args: - - create - - --host={{- include "kube-prometheus-stack.operator.admission-webhook.dnsNames" . | replace "\n" "," }} - - --namespace={{ template "kube-prometheus-stack.namespace" . }} - - --secret-name={{ template "kube-prometheus-stack.fullname" . }}-admission - {{- with .Values.prometheusOperator.admissionWebhooks.createSecretJob }} - securityContext: - {{ toYaml .securityContext | nindent 12 }} - {{- end }} - resources: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.patch.resources | indent 12 }} - restartPolicy: OnFailure - serviceAccountName: {{ template "kube-prometheus-stack.fullname" . }}-admission - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- with .Values.prometheusOperator.admissionWebhooks.patch.nodeSelector }} -{{ toYaml . | indent 8 }} -{{- end }} - {{- with .Values.prometheusOperator.admissionWebhooks.patch.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- with .Values.prometheusOperator.admissionWebhooks.patch.tolerations }} -{{ toYaml . | indent 8 }} - {{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.patch.securityContext }} - securityContext: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.patch.securityContext | indent 8 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml deleted file mode 100644 index 5639cc9e80..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml +++ /dev/null @@ -1,74 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission-patch - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded -{{- with .Values.prometheusOperator.admissionWebhooks.patch.annotations }} -{{ toYaml . | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -spec: - {{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }} - # Alpha feature since k8s 1.12 - ttlSecondsAfterFinished: 0 - {{- end }} - template: - metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission-patch -{{- with .Values.prometheusOperator.admissionWebhooks.patch.podAnnotations }} - annotations: -{{ toYaml . | indent 8 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 8 }} - spec: - {{- if .Values.prometheusOperator.admissionWebhooks.patch.priorityClassName }} - priorityClassName: {{ .Values.prometheusOperator.admissionWebhooks.patch.priorityClassName }} - {{- end }} - containers: - - name: patch - {{- $registry := include "monitoring_registry" . | default .Values.prometheusOperator.admissionWebhooks.patch.image.registry -}} - {{- if .Values.prometheusOperator.admissionWebhooks.patch.image.sha }} - image: {{ $registry }}/{{ .Values.prometheusOperator.admissionWebhooks.patch.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.tag }}@sha256:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.sha }} - {{- else }} - image: {{ $registry }}/{{ .Values.prometheusOperator.admissionWebhooks.patch.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.tag }} - {{- end }} - imagePullPolicy: {{ .Values.prometheusOperator.admissionWebhooks.patch.image.pullPolicy }} - args: - - patch - - --webhook-name={{ template "kube-prometheus-stack.fullname" . }}-admission - - --namespace={{ template "kube-prometheus-stack.namespace" . }} - - --secret-name={{ template "kube-prometheus-stack.fullname" . }}-admission - - --patch-failure-policy={{ .Values.prometheusOperator.admissionWebhooks.failurePolicy }} - {{- with .Values.prometheusOperator.admissionWebhooks.patchWebhookJob }} - securityContext: - {{ toYaml .securityContext | nindent 12 }} - {{- end }} - resources: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.patch.resources | indent 12 }} - restartPolicy: OnFailure - serviceAccountName: {{ template "kube-prometheus-stack.fullname" . }}-admission - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- with .Values.prometheusOperator.admissionWebhooks.patch.nodeSelector }} -{{ toYaml . | indent 8 }} -{{- end }} - {{- with .Values.prometheusOperator.admissionWebhooks.patch.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- with .Values.prometheusOperator.admissionWebhooks.patch.tolerations }} -{{ toYaml . | indent 8 }} - {{- end }} -{{- if .Values.prometheusOperator.admissionWebhooks.patch.securityContext }} - securityContext: -{{ toYaml .Values.prometheusOperator.admissionWebhooks.patch.securityContext | indent 8 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml deleted file mode 100644 index 864deb52a0..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "kubernetes") }} -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission-create - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": pre-install,pre-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded - ## Ensure this is run before the job - "helm.sh/hook-weight": "-5" - {{- with .Values.prometheusOperator.admissionWebhooks.annotations }} - {{ toYaml . | nindent 4 }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-create - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -spec: - podSelector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-create - {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} - {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} - {{- else }} - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 6 }} - {{- end }} - egress: - - {} - policyTypes: - - Egress -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml deleted file mode 100644 index 076c467004..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "kubernetes") }} -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission-patch - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded - ## Ensure this is run before the job - "helm.sh/hook-weight": "-5" - {{- with .Values.prometheusOperator.admissionWebhooks.patch.annotations }} - {{ toYaml . | nindent 4 }} - {{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -spec: - podSelector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch - {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} - {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} - {{- else }} - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 6 }} - {{- end }} - egress: - - {} - policyTypes: - - Egress -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml deleted file mode 100644 index 92c624001b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - annotations: - "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded -{{- if .Values.global.rbac.pspAnnotations }} -{{ toYaml .Values.global.rbac.pspAnnotations | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-admission - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 4 }} -spec: - privileged: false - # Allow core volume types. - volumes: - - 'configMap' - - 'emptyDir' - - 'projected' - - 'secret' - - 'downwardAPI' - - 'persistentVolumeClaim' - hostNetwork: false - hostIPC: false - hostPID: false - runAsUser: - # Permits the container to run with root privileges as well. - rule: 'RunAsAny' - seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - readOnlyRootFilesystem: false -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml deleted file mode 100644 index f15abf4395..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -rules: - - apiGroups: - - "" - resources: - - secrets - verbs: - - get - - create -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml deleted file mode 100644 index 30bde920b6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "kube-prometheus-stack.fullname" . }}-admission -subjects: - - kind: ServiceAccount - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml deleted file mode 100644 index 8dab40c609..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.prometheusOperator.admissionWebhooks.patch.serviceAccount.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -automountServiceAccountToken: {{ .Values.prometheusOperator.admissionWebhooks.patch.serviceAccount.automountServiceAccountToken }} -{{- if .Values.global.imagePullSecrets }} -imagePullSecrets: -{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml deleted file mode 100644 index 91d96b3845..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml +++ /dev/null @@ -1,81 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled }} -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission -{{- if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }} - annotations: - certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-admission" (include "kube-prometheus-stack.namespace" .) (include "kube-prometheus-stack.fullname" .) | quote }} - cert-manager.io/inject-ca-from: {{ printf "%s/%s-admission" (include "kube-prometheus-stack.namespace" .) (include "kube-prometheus-stack.fullname" .) | quote }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -webhooks: - - name: prometheusrulemutate.monitoring.coreos.com - {{- if eq .Values.prometheusOperator.admissionWebhooks.failurePolicy "IgnoreOnInstallOnly" }} - failurePolicy: {{ .Release.IsInstall | ternary "Ignore" "Fail" }} - {{- else if .Values.prometheusOperator.admissionWebhooks.failurePolicy }} - failurePolicy: {{ .Values.prometheusOperator.admissionWebhooks.failurePolicy }} - {{- else if .Values.prometheusOperator.admissionWebhooks.patch.enabled }} - failurePolicy: Ignore - {{- else }} - failurePolicy: Fail - {{- end }} - rules: - - apiGroups: - - monitoring.coreos.com - apiVersions: - - "*" - resources: - - prometheusrules - operations: - - CREATE - - UPDATE - clientConfig: - service: - namespace: {{ template "kube-prometheus-stack.namespace" . }} - name: {{ template "kube-prometheus-stack.operator.fullname" $ }}{{ if .Values.prometheusOperator.admissionWebhooks.deployment.enabled }}-webhook{{ end }} - path: /admission-prometheusrules/mutate - {{- if and .Values.prometheusOperator.admissionWebhooks.caBundle (not .Values.prometheusOperator.admissionWebhooks.patch.enabled) (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} - caBundle: {{ .Values.prometheusOperator.admissionWebhooks.caBundle }} - {{- end }} - timeoutSeconds: {{ .Values.prometheusOperator.admissionWebhooks.timeoutSeconds }} - admissionReviewVersions: ["v1", "v1beta1"] - sideEffects: None - {{- if or .Values.prometheusOperator.denyNamespaces .Values.prometheusOperator.namespaces .Values.prometheusOperator.admissionWebhooks.namespaceSelector }} - namespaceSelector: - {{- with (omit .Values.prometheusOperator.admissionWebhooks.namespaceSelector "matchExpressions") }} - {{- toYaml . | nindent 6 }} - {{- end }} - {{- if or .Values.prometheusOperator.denyNamespaces .Values.prometheusOperator.namespaces .Values.prometheusOperator.admissionWebhooks.namespaceSelector.matchExpressions }} - matchExpressions: - {{- with (.Values.prometheusOperator.admissionWebhooks.namespaceSelector.matchExpressions) }} - {{- toYaml . | nindent 6 }} - {{- end }} - {{- if .Values.prometheusOperator.denyNamespaces }} - - key: kubernetes.io/metadata.name - operator: NotIn - values: - {{- range $namespace := mustUniq .Values.prometheusOperator.denyNamespaces }} - - {{ $namespace }} - {{- end }} - {{- else if and .Values.prometheusOperator.namespaces .Values.prometheusOperator.namespaces.additional }} - - key: kubernetes.io/metadata.name - operator: In - values: - {{- if and .Values.prometheusOperator.namespaces.releaseNamespace (default .Values.prometheusOperator.namespaces.releaseNamespace true) }} - {{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} - - {{ $namespace }} - {{- end }} - {{- range $namespace := mustUniq .Values.prometheusOperator.namespaces.additional }} - - {{ $namespace }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} - {{- with .Values.prometheusOperator.admissionWebhooks.objectSelector }} - objectSelector: - {{- toYaml . | nindent 6 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml deleted file mode 100644 index f21a9a72b1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml +++ /dev/null @@ -1,81 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled }} -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission -{{- if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }} - annotations: - certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-admission" (include "kube-prometheus-stack.namespace" .) (include "kube-prometheus-stack.fullname" .) | quote }} - cert-manager.io/inject-ca-from: {{ printf "%s/%s-admission" (include "kube-prometheus-stack.namespace" .) (include "kube-prometheus-stack.fullname" .) | quote }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-admission - {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} -webhooks: - - name: prometheusrulemutate.monitoring.coreos.com - {{- if eq .Values.prometheusOperator.admissionWebhooks.failurePolicy "IgnoreOnInstallOnly" }} - failurePolicy: {{ .Release.IsInstall | ternary "Ignore" "Fail" }} - {{- else if .Values.prometheusOperator.admissionWebhooks.failurePolicy }} - failurePolicy: {{ .Values.prometheusOperator.admissionWebhooks.failurePolicy }} - {{- else if .Values.prometheusOperator.admissionWebhooks.patch.enabled }} - failurePolicy: Ignore - {{- else }} - failurePolicy: Fail - {{- end }} - rules: - - apiGroups: - - monitoring.coreos.com - apiVersions: - - "*" - resources: - - prometheusrules - operations: - - CREATE - - UPDATE - clientConfig: - service: - namespace: {{ template "kube-prometheus-stack.namespace" . }} - name: {{ template "kube-prometheus-stack.operator.fullname" $ }}{{ if .Values.prometheusOperator.admissionWebhooks.deployment.enabled }}-webhook{{ end }} - path: /admission-prometheusrules/validate - {{- if and .Values.prometheusOperator.admissionWebhooks.caBundle (not .Values.prometheusOperator.admissionWebhooks.patch.enabled) (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} - caBundle: {{ .Values.prometheusOperator.admissionWebhooks.caBundle }} - {{- end }} - timeoutSeconds: {{ .Values.prometheusOperator.admissionWebhooks.timeoutSeconds }} - admissionReviewVersions: ["v1", "v1beta1"] - sideEffects: None - {{- if or .Values.prometheusOperator.denyNamespaces .Values.prometheusOperator.namespaces .Values.prometheusOperator.admissionWebhooks.namespaceSelector }} - namespaceSelector: - {{- with (omit .Values.prometheusOperator.admissionWebhooks.namespaceSelector "matchExpressions") }} - {{- toYaml . | nindent 6 }} - {{- end }} - {{- if or .Values.prometheusOperator.denyNamespaces .Values.prometheusOperator.namespaces .Values.prometheusOperator.admissionWebhooks.namespaceSelector.matchExpressions }} - matchExpressions: - {{- with (.Values.prometheusOperator.admissionWebhooks.namespaceSelector.matchExpressions) }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- if .Values.prometheusOperator.denyNamespaces }} - - key: kubernetes.io/metadata.name - operator: NotIn - values: - {{- range $namespace := mustUniq .Values.prometheusOperator.denyNamespaces }} - - {{ $namespace }} - {{- end }} - {{- else if and .Values.prometheusOperator.namespaces .Values.prometheusOperator.namespaces.additional }} - - key: kubernetes.io/metadata.name - operator: In - values: - {{- if and .Values.prometheusOperator.namespaces.releaseNamespace (default .Values.prometheusOperator.namespaces.releaseNamespace true) }} - {{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} - - {{ $namespace }} - {{- end }} - {{- range $namespace := mustUniq .Values.prometheusOperator.namespaces.additional }} - - {{ $namespace }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} - {{- with .Values.prometheusOperator.admissionWebhooks.objectSelector }} - objectSelector: - {{- toYaml . | nindent 6 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/aggregate-clusterroles.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/aggregate-clusterroles.yaml deleted file mode 100644 index 0c52000d6d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/aggregate-clusterroles.yaml +++ /dev/null @@ -1,29 +0,0 @@ -{{/* This file is based on https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/rbac-crd.md */}} -{{- if and .Values.global.rbac.create .Values.global.rbac.createAggregateClusterRoles }} -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-crd-view - labels: - rbac.authorization.k8s.io/aggregate-to-admin: "true" - rbac.authorization.k8s.io/aggregate-to-edit: "true" - rbac.authorization.k8s.io/aggregate-to-view: "true" - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -rules: -- apiGroups: ["monitoring.coreos.com"] - resources: ["alertmanagers", "alertmanagerconfigs", "podmonitors", "probes", "prometheuses", "prometheusagents", "prometheusrules", "scrapeconfigs", "servicemonitors"] - verbs: ["get", "list", "watch"] ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-crd-edit - labels: - rbac.authorization.k8s.io/aggregate-to-edit: "true" - rbac.authorization.k8s.io/aggregate-to-admin: "true" - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -rules: -- apiGroups: ["monitoring.coreos.com"] - resources: ["alertmanagers", "alertmanagerconfigs", "podmonitors", "probes", "prometheuses", "prometheusagents", "prometheusrules", "scrapeconfigs", "servicemonitors"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/certmanager.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/certmanager.yaml deleted file mode 100644 index cb27e49f48..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/certmanager.yaml +++ /dev/null @@ -1,55 +0,0 @@ -{{- if .Values.prometheusOperator.admissionWebhooks.certManager.enabled -}} -{{- if not .Values.prometheusOperator.admissionWebhooks.certManager.issuerRef -}} -# Create a selfsigned Issuer, in order to create a root CA certificate for -# signing webhook serving certificates -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-self-signed-issuer - namespace: {{ template "kube-prometheus-stack.namespace" . }} -spec: - selfSigned: {} ---- -# Generate a CA Certificate used to sign certificates for the webhook -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-root-cert - namespace: {{ template "kube-prometheus-stack.namespace" . }} -spec: - secretName: {{ template "kube-prometheus-stack.fullname" . }}-root-cert - duration: {{ .Values.prometheusOperator.admissionWebhooks.certManager.rootCert.duration | default "43800h0m0s" | quote }} - issuerRef: - name: {{ template "kube-prometheus-stack.fullname" . }}-self-signed-issuer - commonName: "ca.webhook.kube-prometheus-stack" - isCA: true ---- -# Create an Issuer that uses the above generated CA certificate to issue certs -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-root-issuer - namespace: {{ template "kube-prometheus-stack.namespace" . }} -spec: - ca: - secretName: {{ template "kube-prometheus-stack.fullname" . }}-root-cert -{{- end }} ---- -# generate a server certificate for the apiservices to use -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - namespace: {{ template "kube-prometheus-stack.namespace" . }} -spec: - secretName: {{ template "kube-prometheus-stack.fullname" . }}-admission - duration: {{ .Values.prometheusOperator.admissionWebhooks.certManager.admissionCert.duration | default "8760h0m0s" | quote }} - issuerRef: - {{- if .Values.prometheusOperator.admissionWebhooks.certManager.issuerRef }} - {{- toYaml .Values.prometheusOperator.admissionWebhooks.certManager.issuerRef | nindent 4 }} - {{- else }} - name: {{ template "kube-prometheus-stack.fullname" . }}-root-issuer - {{- end }} - dnsNames: - {{- include "kube-prometheus-stack.operator.admission-webhook.dnsNames" . | splitList "\n" | toYaml | nindent 4 }} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/ciliumnetworkpolicy.yaml deleted file mode 100644 index 07e2e99967..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/ciliumnetworkpolicy.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "cilium") }} -apiVersion: cilium.io/v2 -kind: CiliumNetworkPolicy -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -spec: - endpointSelector: - matchLabels: - {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} - app: {{ template "kube-prometheus-stack.name" . }}-operator - {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} - {{- else }} - {{- include "kube-prometheus-stack.prometheus-operator.labels" $ | nindent 6 }} - {{- end }} - egress: - {{- if and .Values.prometheusOperator.networkPolicy.cilium .Values.prometheusOperator.networkPolicy.cilium.egress }} - {{ toYaml .Values.prometheusOperator.networkPolicy.cilium.egress | nindent 6 }} - {{- else }} - - toEntities: - - kube-apiserver - {{- end }} - ingress: - - toPorts: - - ports: - {{- if .Values.prometheusOperator.tls.enabled }} - - port: {{ .Values.prometheusOperator.tls.internalPort | quote }} - {{- else }} - - port: "8080" - {{- end }} - protocol: "TCP" - {{- if not .Values.prometheusOperator.tls.enabled }} - rules: - http: - - method: "GET" - path: "/metrics" - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/clusterrole.yaml deleted file mode 100644 index fd11b69eed..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/clusterrole.yaml +++ /dev/null @@ -1,109 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -rules: -- apiGroups: - - monitoring.coreos.com - resources: - - alertmanagers - - alertmanagers/finalizers - - alertmanagers/status - - alertmanagerconfigs - - prometheuses - - prometheuses/finalizers - - prometheuses/status - - prometheusagents - - prometheusagents/finalizers - - prometheusagents/status - - thanosrulers - - thanosrulers/finalizers - - thanosrulers/status - - scrapeconfigs - - servicemonitors - - podmonitors - - probes - - prometheusrules - verbs: - - '*' -- apiGroups: - - apps - resources: - - statefulsets - verbs: - - '*' -- apiGroups: - - "" - resources: - - configmaps - - secrets - verbs: - - '*' -- apiGroups: - - "" - resources: - - pods - verbs: - - list - - delete -- apiGroups: - - "" - resources: - - services - - services/finalizers - - endpoints - verbs: - - get - - create - - update - - delete -- apiGroups: - - "" - resources: - - nodes - verbs: - - list - - watch -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - events - verbs: - - patch - - create -- apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - get - - list - - watch -- apiGroups: - - storage.k8s.io - resources: - - storageclasses - verbs: - - get -{{- if .Capabilities.APIVersions.Has "discovery.k8s.io/v1/EndpointSlice" }} -- apiGroups: - - discovery.k8s.io - resources: - - endpointslices - verbs: - - get - - list - - watch -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/clusterrolebinding.yaml deleted file mode 100644 index ad9e3ef6c5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/clusterrolebinding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "kube-prometheus-stack.operator.fullname" . }} -subjects: -- kind: ServiceAccount - name: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/deployment.yaml deleted file mode 100644 index b71e7d25d6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/deployment.yaml +++ /dev/null @@ -1,207 +0,0 @@ -{{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} -{{- $defaultKubeletSvcName := printf "%s-kubelet" (include "kube-prometheus-stack.fullname" .) }} -{{- if .Values.prometheusOperator.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -{{- if .Values.prometheusOperator.labels }} -{{ toYaml .Values.prometheusOperator.labels | indent 4 }} -{{- end }} -{{- if .Values.prometheusOperator.annotations }} - annotations: -{{ toYaml .Values.prometheusOperator.annotations | indent 4 }} -{{- end }} -spec: - replicas: 1 - revisionHistoryLimit: {{ .Values.prometheusOperator.revisionHistoryLimit }} - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-operator - release: {{ $.Release.Name | quote }} - {{- with .Values.prometheusOperator.strategy }} - strategy: - {{- toYaml . | nindent 4 }} - {{- end }} - template: - metadata: - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 8 }} -{{- if .Values.prometheusOperator.podLabels }} -{{ toYaml .Values.prometheusOperator.podLabels | indent 8 }} -{{- end }} -{{- if .Values.prometheusOperator.podAnnotations }} - annotations: -{{ toYaml .Values.prometheusOperator.podAnnotations | indent 8 }} -{{- end }} - spec: - {{- if .Values.prometheusOperator.priorityClassName }} - priorityClassName: {{ .Values.prometheusOperator.priorityClassName }} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- include "kube-prometheus-stack.imagePullSecrets" . | indent 8 }} - {{- end }} - containers: - - name: {{ template "kube-prometheus-stack.name" . }} - {{- $base_registry := (include "monitoring_registry" .) }} - {{- $configReloaderRegistry := $base_registry | default .Values.prometheusOperator.prometheusConfigReloader.image.registry -}} - {{- $operatorRegistry := $base_registry | default .Values.prometheusOperator.image.registry -}} - {{- $thanosRegistry := $base_registry | default .Values.prometheusOperator.thanosImage.registry -}} - {{- if .Values.prometheusOperator.image.sha }} - image: "{{ $operatorRegistry }}/{{ .Values.prometheusOperator.image.repository }}:{{ .Values.prometheusOperator.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.prometheusOperator.image.sha }}" - {{- else }} - image: "{{ $operatorRegistry }}/{{ .Values.prometheusOperator.image.repository }}:{{ .Values.prometheusOperator.image.tag | default .Chart.AppVersion }}" - {{- end }} - imagePullPolicy: "{{ .Values.prometheusOperator.image.pullPolicy }}" - args: - {{- if .Values.prometheusOperator.kubeletService.enabled }} - - --kubelet-service={{ .Values.prometheusOperator.kubeletService.namespace }}/{{ default $defaultKubeletSvcName .Values.prometheusOperator.kubeletService.name }} - {{- if .Values.prometheusOperator.kubeletService.selector }} - - --kubelet-selector={{ .Values.prometheusOperator.kubeletService.selector }} - {{- end }} - {{- end }} - {{- if .Values.prometheusOperator.logFormat }} - - --log-format={{ .Values.prometheusOperator.logFormat }} - {{- end }} - {{- if .Values.prometheusOperator.logLevel }} - - --log-level={{ .Values.prometheusOperator.logLevel }} - {{- end }} - {{- if .Values.prometheusOperator.denyNamespaces }} - - --deny-namespaces={{ tpl (.Values.prometheusOperator.denyNamespaces | join ",") $ }} - {{- end }} - {{- with $.Values.prometheusOperator.namespaces }} - {{- $namespaces := list }} - {{- if .releaseNamespace }} - {{- $namespaces = append $namespaces $namespace }} - {{- end }} - {{- if .additional }} - {{- range $ns := .additional }} - {{- $namespaces = append $namespaces (tpl $ns $) }} - {{- end }} - {{- end }} - - --namespaces={{ $namespaces | mustUniq | join "," }} - {{- end }} - - --localhost=127.0.0.1 - {{- if .Values.prometheusOperator.prometheusDefaultBaseImage }} - - --prometheus-default-base-image={{ $base_registry | default .Values.prometheusOperator.prometheusDefaultBaseImageRegistry }}/{{ .Values.prometheusOperator.prometheusDefaultBaseImage }} - {{- end }} - {{- if .Values.prometheusOperator.alertmanagerDefaultBaseImage }} - - --alertmanager-default-base-image={{ $base_registry | default .Values.prometheusOperator.alertmanagerDefaultBaseImageRegistry }}/{{ .Values.prometheusOperator.alertmanagerDefaultBaseImage }} - {{- end }} - {{- if .Values.prometheusOperator.prometheusConfigReloader.image.sha }} - - --prometheus-config-reloader={{ $configReloaderRegistry }}/{{ .Values.prometheusOperator.prometheusConfigReloader.image.repository }}:{{ .Values.prometheusOperator.prometheusConfigReloader.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.prometheusOperator.prometheusConfigReloader.image.sha }} - {{- else }} - - --prometheus-config-reloader={{ $configReloaderRegistry }}/{{ .Values.prometheusOperator.prometheusConfigReloader.image.repository }}:{{ .Values.prometheusOperator.prometheusConfigReloader.image.tag | default .Chart.AppVersion }} - {{- end }} - - --config-reloader-cpu-request={{ (((.Values.prometheusOperator.prometheusConfigReloader.resources).requests).cpu) | default 0 }} - - --config-reloader-cpu-limit={{ (((.Values.prometheusOperator.prometheusConfigReloader.resources).limits).cpu) | default 0 }} - - --config-reloader-memory-request={{ (((.Values.prometheusOperator.prometheusConfigReloader.resources).requests).memory) | default 0 }} - - --config-reloader-memory-limit={{ (((.Values.prometheusOperator.prometheusConfigReloader.resources).limits).memory) | default 0 }} - {{- if .Values.prometheusOperator.prometheusConfigReloader.enableProbe }} - - --enable-config-reloader-probes=true - {{- end }} - {{- if .Values.prometheusOperator.alertmanagerInstanceNamespaces }} - - --alertmanager-instance-namespaces={{ .Values.prometheusOperator.alertmanagerInstanceNamespaces | join "," }} - {{- end }} - {{- if .Values.prometheusOperator.alertmanagerInstanceSelector }} - - --alertmanager-instance-selector={{ .Values.prometheusOperator.alertmanagerInstanceSelector }} - {{- end }} - {{- if .Values.prometheusOperator.alertmanagerConfigNamespaces }} - - --alertmanager-config-namespaces={{ .Values.prometheusOperator.alertmanagerConfigNamespaces | join "," }} - {{- end }} - {{- if .Values.prometheusOperator.prometheusInstanceNamespaces }} - - --prometheus-instance-namespaces={{ .Values.prometheusOperator.prometheusInstanceNamespaces | join "," }} - {{- end }} - {{- if .Values.prometheusOperator.prometheusInstanceSelector }} - - --prometheus-instance-selector={{ .Values.prometheusOperator.prometheusInstanceSelector }} - {{- end }} - {{- if .Values.prometheusOperator.thanosImage.sha }} - - --thanos-default-base-image={{ $thanosRegistry }}/{{ .Values.prometheusOperator.thanosImage.repository }}:{{ .Values.prometheusOperator.thanosImage.tag }}@sha256:{{ .Values.prometheusOperator.thanosImage.sha }} - {{- else }} - - --thanos-default-base-image={{ $thanosRegistry }}/{{ .Values.prometheusOperator.thanosImage.repository }}:{{ .Values.prometheusOperator.thanosImage.tag }} - {{- end }} - {{- if .Values.prometheusOperator.thanosRulerInstanceNamespaces }} - - --thanos-ruler-instance-namespaces={{ .Values.prometheusOperator.thanosRulerInstanceNamespaces | join "," }} - {{- end }} - {{- if .Values.prometheusOperator.thanosRulerInstanceSelector }} - - --thanos-ruler-instance-selector={{ .Values.prometheusOperator.thanosRulerInstanceSelector }} - {{- end }} - {{- if .Values.prometheusOperator.secretFieldSelector }} - - --secret-field-selector={{ tpl (.Values.prometheusOperator.secretFieldSelector) $ }} - {{- end }} - {{- if .Values.prometheusOperator.clusterDomain }} - - --cluster-domain={{ .Values.prometheusOperator.clusterDomain }} - {{- end }} - {{- if .Values.prometheusOperator.tls.enabled }} - - --web.enable-tls=true - - --web.cert-file=/cert/{{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}tls.crt{{ else }}cert{{ end }} - - --web.key-file=/cert/{{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}tls.key{{ else }}key{{ end }} - - --web.listen-address=:{{ .Values.prometheusOperator.tls.internalPort }} - - --web.tls-min-version={{ .Values.prometheusOperator.tls.tlsMinVersion }} - ports: - - containerPort: {{ .Values.prometheusOperator.tls.internalPort }} - name: https - {{- else }} - ports: - - containerPort: 8080 - name: http - {{- end }} - env: - {{- range $key, $value := .Values.prometheusOperator.env }} - - name: {{ $key }} - value: {{ $value | quote }} - {{- end }} - resources: -{{ toYaml .Values.prometheusOperator.resources | indent 12 }} - securityContext: -{{ toYaml .Values.prometheusOperator.containerSecurityContext | indent 12 }} - volumeMounts: - {{- if .Values.prometheusOperator.tls.enabled }} - - name: tls-secret - mountPath: /cert - readOnly: true - {{- end }} - {{- with .Values.prometheusOperator.extraVolumeMounts }} - {{- toYaml . | nindent 12 }} - {{- end }} - volumes: - {{- if .Values.prometheusOperator.tls.enabled }} - - name: tls-secret - secret: - defaultMode: 420 - secretName: {{ template "kube-prometheus-stack.fullname" . }}-admission - {{- end }} - {{- with .Values.prometheusOperator.extraVolumes }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.prometheusOperator.dnsConfig }} - dnsConfig: -{{ toYaml . | indent 8 }} - {{- end }} -{{- if .Values.prometheusOperator.securityContext }} - securityContext: -{{ toYaml .Values.prometheusOperator.securityContext | indent 8 }} -{{- end }} - serviceAccountName: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }} - automountServiceAccountToken: {{ .Values.prometheusOperator.automountServiceAccountToken }} -{{- if .Values.prometheusOperator.hostNetwork }} - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet -{{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} -{{- with .Values.prometheusOperator.nodeSelector }} -{{ toYaml . | indent 8 }} -{{- end }} - {{- with .Values.prometheusOperator.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} -{{- with .Values.prometheusOperator.tolerations }} -{{ toYaml . | indent 8 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/networkpolicy.yaml deleted file mode 100644 index cfd5b0b8c7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/networkpolicy.yaml +++ /dev/null @@ -1,29 +0,0 @@ -{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "kubernetes") }} -apiVersion: {{ template "kube-prometheus-stack.prometheus.networkPolicy.apiVersion" . }} -kind: NetworkPolicy -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -spec: - egress: - - {} - ingress: - - ports: - {{- if .Values.prometheusOperator.tls.enabled }} - - port: {{ .Values.prometheusOperator.tls.internalPort }} - {{- else }} - - port: 8080 - {{- end }} - policyTypes: - - Egress - - Ingress - podSelector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-operator - release: {{ $.Release.Name | quote }} - {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} - {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp-clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp-clusterrole.yaml deleted file mode 100644 index 9766238968..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp-clusterrole.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }}-psp - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -rules: -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} -- apiGroups: ['policy'] -{{- else }} -- apiGroups: ['extensions'] -{{- end }} - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "kube-prometheus-stack.operator.fullname" . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp-clusterrolebinding.yaml deleted file mode 100644 index 01f5f3d9dd..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp-clusterrolebinding.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }}-psp - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "kube-prometheus-stack.operator.fullname" . }}-psp -subjects: - - kind: ServiceAccount - name: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp.yaml deleted file mode 100644 index 0943b5f563..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/psp.yaml +++ /dev/null @@ -1,46 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -{{- if .Values.global.rbac.pspAnnotations }} - annotations: -{{ toYaml .Values.global.rbac.pspAnnotations | indent 4 }} -{{- end }} -spec: - privileged: false - # Allow core volume types. - volumes: - - 'configMap' - - 'emptyDir' - - 'projected' - - 'secret' - - 'downwardAPI' - - 'persistentVolumeClaim' - hostNetwork: {{ .Values.prometheusOperator.hostNetwork }} - hostIPC: false - hostPID: false - runAsUser: - # Permits the container to run with root privileges as well. - rule: 'RunAsAny' - seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - readOnlyRootFilesystem: false -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/service.yaml deleted file mode 100644 index 72e0788abf..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/service.yaml +++ /dev/null @@ -1,61 +0,0 @@ -{{- if .Values.prometheusOperator.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -{{- if .Values.prometheusOperator.service.labels }} -{{ toYaml .Values.prometheusOperator.service.labels | indent 4 }} -{{- end }} -{{- if .Values.prometheusOperator.service.annotations }} - annotations: -{{ toYaml .Values.prometheusOperator.service.annotations | indent 4 }} -{{- end }} -spec: -{{- if .Values.prometheusOperator.service.clusterIP }} - clusterIP: {{ .Values.prometheusOperator.service.clusterIP }} -{{- end }} -{{- if .Values.prometheusOperator.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.prometheusOperator.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.prometheusOperator.service.ipDualStack.ipFamilyPolicy }} -{{- end }} -{{- if .Values.prometheusOperator.service.externalIPs }} - externalIPs: -{{ toYaml .Values.prometheusOperator.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.prometheusOperator.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.prometheusOperator.service.loadBalancerIP }} -{{- end }} -{{- if .Values.prometheusOperator.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.prometheusOperator.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} -{{- if ne .Values.prometheusOperator.service.type "ClusterIP" }} - externalTrafficPolicy: {{ .Values.prometheusOperator.service.externalTrafficPolicy }} -{{- end }} - ports: - {{- if not .Values.prometheusOperator.tls.enabled }} - - name: http - {{- if eq .Values.prometheusOperator.service.type "NodePort" }} - nodePort: {{ .Values.prometheusOperator.service.nodePort }} - {{- end }} - port: 8080 - targetPort: http - {{- end }} - {{- if .Values.prometheusOperator.tls.enabled }} - - name: https - {{- if eq .Values.prometheusOperator.service.type "NodePort"}} - nodePort: {{ .Values.prometheusOperator.service.nodePortTls }} - {{- end }} - port: 443 - targetPort: https - {{- end }} - selector: - app: {{ template "kube-prometheus-stack.name" . }}-operator - release: {{ $.Release.Name | quote }} - type: "{{ .Values.prometheusOperator.service.type }}" -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/serviceaccount.yaml deleted file mode 100644 index 4f84974f9b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/serviceaccount.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.serviceAccount.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -automountServiceAccountToken: {{ .Values.prometheusOperator.serviceAccount.automountServiceAccountToken }} -{{- if .Values.global.imagePullSecrets }} -imagePullSecrets: -{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/servicemonitor.yaml deleted file mode 100644 index cbe79e1253..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/servicemonitor.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.serviceMonitor.selfMonitor }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -{{- with .Values.prometheusOperator.serviceMonitor.additionalLabels }} -{{ toYaml . | indent 4 }} -{{- end }} -spec: - {{- include "servicemonitor.scrapeLimits" .Values.prometheusOperator.serviceMonitor | nindent 2 }} - endpoints: - {{- if .Values.prometheusOperator.tls.enabled }} - - port: https - scheme: https - tlsConfig: - serverName: {{ template "kube-prometheus-stack.operator.fullname" . }} - ca: - secret: - name: {{ template "kube-prometheus-stack.fullname" . }}-admission - key: {{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}ca.crt{{ else }}ca{{ end }} - optional: false - {{- else }} - - port: http - {{- end }} - honorLabels: true - {{- if .Values.prometheusOperator.serviceMonitor.interval }} - interval: {{ .Values.prometheusOperator.serviceMonitor.interval }} - {{- end }} - metricRelabelings: - {{- if .Values.prometheusOperator.serviceMonitor.metricRelabelings }} - {{ tpl (toYaml .Values.prometheusOperator.serviceMonitor.metricRelabelings | indent 6) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.prometheusOperator.serviceMonitor.relabelings }} - relabelings: -{{ toYaml .Values.prometheusOperator.serviceMonitor.relabelings | indent 6 }} -{{- end }} - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-operator - release: {{ $.Release.Name | quote }} - namespaceSelector: - matchNames: - - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/verticalpodautoscaler.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/verticalpodautoscaler.yaml deleted file mode 100644 index f225d16dde..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus-operator/verticalpodautoscaler.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.prometheusOperator.verticalPodAutoscaler.enabled) }} -apiVersion: autoscaling.k8s.io/v1 -kind: VerticalPodAutoscaler -metadata: - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} -spec: - {{- with .Values.prometheusOperator.verticalPodAutoscaler.recommenders }} - recommenders: - {{- toYaml . | nindent 4 }} - {{- end }} - resourcePolicy: - containerPolicies: - - containerName: {{ template "kube-prometheus-stack.name" . }} - {{- with .Values.prometheusOperator.verticalPodAutoscaler.controlledResources }} - controlledResources: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- if .Values.prometheusOperator.verticalPodAutoscaler.controlledValues }} - controlledValues: {{ .Values.prometheusOperator.verticalPodAutoscaler.controlledValues }} - {{- end }} - {{- if .Values.prometheusOperator.verticalPodAutoscaler.maxAllowed }} - maxAllowed: - {{- toYaml .Values.prometheusOperator.verticalPodAutoscaler.maxAllowed | nindent 8 }} - {{- end }} - {{- if .Values.prometheusOperator.verticalPodAutoscaler.minAllowed }} - minAllowed: - {{- toYaml .Values.prometheusOperator.verticalPodAutoscaler.minAllowed | nindent 8 }} - {{- end }} - targetRef: - apiVersion: apps/v1 - kind: Deployment - name: {{ template "kube-prometheus-stack.operator.fullname" . }} - {{- with .Values.prometheusOperator.verticalPodAutoscaler.updatePolicy }} - updatePolicy: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/_rules.tpl b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/_rules.tpl deleted file mode 100644 index 4a8213d089..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/_rules.tpl +++ /dev/null @@ -1,44 +0,0 @@ -{{- /* -Generated file. Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- define "rules.names" }} -rules: - - "alertmanager.rules" - - "config-reloaders" - - "etcd" - - "general.rules" - - "k8s.rules.container-cpu-usage-seconds-total" - - "k8s.rules.container-memory-cache" - - "k8s.rules.container-memory-rss" - - "k8s.rules.container-memory-swap" - - "k8s.rules.container-memory-working-set-bytes" - - "k8s.rules.container-resource" - - "k8s.rules.pod-owner" - - "kube-apiserver-availability.rules" - - "kube-apiserver-burnrate.rules" - - "kube-apiserver-histogram.rules" - - "kube-apiserver-slos" - - "kube-prometheus-general.rules" - - "kube-prometheus-node-recording.rules" - - "kube-scheduler.rules" - - "kube-state-metrics" - - "kubelet.rules" - - "kubernetes-apps" - - "kubernetes-resources" - - "kubernetes-storage" - - "kubernetes-system" - - "kubernetes-system-kube-proxy" - - "kubernetes-system-apiserver" - - "kubernetes-system-kubelet" - - "kubernetes-system-controller-manager" - - "kubernetes-system-scheduler" - - "node-exporter.rules" - - "node-exporter" - - "node.rules" - - "node-network" - - "prometheus-operator" - - "prometheus" - - "windows.node.rules" - - "windows.pod.rules" -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalAlertRelabelConfigs.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalAlertRelabelConfigs.yaml deleted file mode 100644 index bff930981a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalAlertRelabelConfigs.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigs }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-am-relabel-confg - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- if .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations }} - annotations: -{{ toYaml .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus-am-relabel-confg -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: - additional-alert-relabel-configs.yaml: {{ toYaml .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigs | b64enc | quote }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalAlertmanagerConfigs.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalAlertmanagerConfigs.yaml deleted file mode 100644 index 2fe8fdb816..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalAlertmanagerConfigs.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.prometheusSpec.additionalAlertManagerConfigs }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-am-confg - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- if .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations }} - annotations: -{{ toYaml .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus-am-confg -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: - additional-alertmanager-configs.yaml: {{ tpl (toYaml .Values.prometheus.prometheusSpec.additionalAlertManagerConfigs) . | b64enc | quote }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalPrometheusRules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalPrometheusRules.yaml deleted file mode 100644 index cb4aabaa7b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalPrometheusRules.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if or .Values.additionalPrometheusRules .Values.additionalPrometheusRulesMap}} -apiVersion: v1 -kind: List -metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-additional-prometheus-rules - namespace: {{ template "kube-prometheus-stack.namespace" . }} -items: -{{- if .Values.additionalPrometheusRulesMap }} -{{- range $prometheusRuleName, $prometheusRule := .Values.additionalPrometheusRulesMap }} - - apiVersion: monitoring.coreos.com/v1 - kind: PrometheusRule - metadata: - name: {{ template "kube-prometheus-stack.name" $ }}-{{ $prometheusRuleName }} - namespace: {{ template "kube-prometheus-stack.namespace" $ }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }} -{{ include "kube-prometheus-stack.labels" $ | indent 8 }} - {{- if $prometheusRule.additionalLabels }} -{{ toYaml $prometheusRule.additionalLabels | indent 8 }} - {{- end }} - spec: - groups: -{{ toYaml $prometheusRule.groups| indent 8 }} -{{- end }} -{{- else }} -{{- range .Values.additionalPrometheusRules }} - - apiVersion: monitoring.coreos.com/v1 - kind: PrometheusRule - metadata: - name: {{ template "kube-prometheus-stack.name" $ }}-{{ .name }} - namespace: {{ template "kube-prometheus-stack.namespace" $ }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }} -{{ include "kube-prometheus-stack.labels" $ | indent 8 }} - {{- if .additionalLabels }} -{{ toYaml .additionalLabels | indent 8 }} - {{- end }} - spec: - groups: -{{ toYaml .groups| indent 8 }} -{{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalScrapeConfigs.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalScrapeConfigs.yaml deleted file mode 100644 index ebdf766fde..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/additionalScrapeConfigs.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.prometheusSpec.additionalScrapeConfigs }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-scrape-confg - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- if .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations }} - annotations: -{{ toYaml .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus-scrape-confg -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: -{{- if eq ( typeOf .Values.prometheus.prometheusSpec.additionalScrapeConfigs ) "string" }} - additional-scrape-configs.yaml: {{ tpl .Values.prometheus.prometheusSpec.additionalScrapeConfigs $ | b64enc | quote }} -{{- else }} - additional-scrape-configs.yaml: {{ tpl (toYaml .Values.prometheus.prometheusSpec.additionalScrapeConfigs) $ | b64enc | quote }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ciliumnetworkpolicy.yaml deleted file mode 100644 index 74d61d7c13..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ciliumnetworkpolicy.yaml +++ /dev/null @@ -1,27 +0,0 @@ -{{- if and .Values.prometheus.networkPolicy.enabled (eq .Values.prometheus.networkPolicy.flavor "cilium") }} -apiVersion: cilium.io/v2 -kind: CiliumNetworkPolicy -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus - {{- include "kube-prometheus-stack.labels" . | nindent 4 }} -spec: - endpointSelector: - {{- if .Values.prometheus.networkPolicy.cilium.endpointSelector }} - {{- toYaml .Values.prometheus.networkPolicy.cilium.endpointSelector | nindent 4 }} - {{- else }} - matchExpressions: - - {key: app.kubernetes.io/name, operator: In, values: [prometheus]} - - {key: prometheus, operator: In, values: [{{ template "kube-prometheus-stack.prometheus.crname" . }}]} - {{- end }} - {{- if and .Values.prometheus.networkPolicy.cilium .Values.prometheus.networkPolicy.cilium.egress }} - egress: - {{ toYaml .Values.prometheus.networkPolicy.cilium.egress | nindent 4 }} - {{- end }} - {{- if and .Values.prometheus.networkPolicy.cilium .Values.prometheus.networkPolicy.cilium.ingress }} - ingress: - {{ toYaml .Values.prometheus.networkPolicy.cilium.ingress | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/clusterrole.yaml deleted file mode 100644 index eabdb24b95..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/clusterrole.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.global.rbac.create }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -rules: -# This permission are not in the kube-prometheus repo -# they're grabbed from https://github.com/prometheus/prometheus/blob/master/documentation/examples/rbac-setup.yml -- apiGroups: [""] - resources: - - nodes - - 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"] -{{/* fix(#3338): add required rules to use node-exporter with the RBAC proxy */}} -{{- if and .Values.nodeExporter.enabled (index .Values "prometheus-node-exporter").kubeRBACProxy.enabled }} -- apiGroups: [ "" ] - resources: - - services/{{ include "prometheus-node-exporter.fullname" (index .Subcharts "prometheus-node-exporter") }} - verbs: [ "get", "list", "watch" ] -{{- end }} -{{- if and .Values.kubeStateMetrics.enabled (index .Values "kube-state-metrics").kubeRBACProxy.enabled }} -- apiGroups: [ "" ] - resources: - - services/{{ include "kube-state-metrics.fullname" (index .Subcharts "kube-state-metrics") }} - verbs: [ "get", "list", "watch" ] -{{- end }} -{{- if .Values.prometheus.additionalRulesForClusterRole }} -{{ toYaml .Values.prometheus.additionalRulesForClusterRole | indent 0 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/clusterrolebinding.yaml deleted file mode 100644 index 9fc4f65da4..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/clusterrolebinding.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.global.rbac.create }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus -subjects: - - kind: ServiceAccount - name: {{ template "kube-prometheus-stack.prometheus.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- end }} - diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/csi-secret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/csi-secret.yaml deleted file mode 100644 index e05382f633..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/csi-secret.yaml +++ /dev/null @@ -1,12 +0,0 @@ -{{- if and .Values.prometheus.prometheusSpec.thanos .Values.prometheus.prometheusSpec.thanos.secretProviderClass }} ---- -apiVersion: secrets-store.csi.x-k8s.io/v1alpha1 -kind: SecretProviderClass -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -spec: -{{ toYaml .Values.prometheus.prometheusSpec.thanos.secretProviderClass | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/extrasecret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/extrasecret.yaml deleted file mode 100644 index 17f3478a46..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/extrasecret.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.prometheus.extraSecret.data -}} -{{- $secretName := printf "prometheus-%s-extra" (include "kube-prometheus-stack.fullname" . ) -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ default $secretName .Values.prometheus.extraSecret.name }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- if .Values.prometheus.extraSecret.annotations }} - annotations: -{{ toYaml .Values.prometheus.extraSecret.annotations | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus - app.kubernetes.io/component: prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: -{{- range $key, $val := .Values.prometheus.extraSecret.data }} - {{ $key }}: {{ $val | b64enc | quote }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingress.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingress.yaml deleted file mode 100644 index d2f6af5dd1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingress.yaml +++ /dev/null @@ -1,77 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.ingress.enabled -}} - {{- $pathType := .Values.prometheus.ingress.pathType | default "ImplementationSpecific" -}} - {{- $serviceName := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "prometheus" -}} - {{- $servicePort := .Values.prometheus.ingress.servicePort | default .Values.prometheus.service.port -}} - {{- $routePrefix := list .Values.prometheus.prometheusSpec.routePrefix -}} - {{- $paths := .Values.prometheus.ingress.paths | default $routePrefix -}} - {{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} - {{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} -apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" . }} -kind: Ingress -metadata: -{{- if .Values.prometheus.ingress.annotations }} - annotations: - {{- tpl (toYaml .Values.prometheus.ingress.annotations) . | nindent 4 }} -{{- end }} - name: {{ $serviceName }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.prometheus.ingress.labels }} -{{ toYaml .Values.prometheus.ingress.labels | indent 4 }} -{{- end }} -spec: - {{- if $apiIsStable }} - {{- if .Values.prometheus.ingress.ingressClassName }} - ingressClassName: {{ .Values.prometheus.ingress.ingressClassName }} - {{- end }} - {{- end }} - rules: - {{- if .Values.prometheus.ingress.hosts }} - {{- range $host := .Values.prometheus.ingress.hosts }} - - host: {{ tpl $host $ }} - http: - paths: - {{- range $p := $paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ $serviceName }} - port: - number: {{ $servicePort }} - {{- else }} - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end }} - {{- end -}} - {{- end -}} - {{- else }} - - http: - paths: - {{- range $p := $paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ $serviceName }} - port: - number: {{ $servicePort }} - {{- else }} - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end }} - {{- end -}} - {{- end -}} - {{- if .Values.prometheus.ingress.tls }} - tls: -{{ tpl (toYaml .Values.prometheus.ingress.tls | indent 4) . }} - {{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingressThanosSidecar.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingressThanosSidecar.yaml deleted file mode 100644 index 3f507cfa9f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingressThanosSidecar.yaml +++ /dev/null @@ -1,77 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.thanosIngress.enabled }} -{{- $pathType := .Values.prometheus.thanosIngress.pathType | default "" }} -{{- $serviceName := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "thanos-discovery" }} -{{- $thanosPort := .Values.prometheus.thanosIngress.servicePort -}} -{{- $routePrefix := list .Values.prometheus.prometheusSpec.routePrefix }} -{{- $paths := .Values.prometheus.thanosIngress.paths | default $routePrefix -}} -{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} -{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} -apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" . }} -kind: Ingress -metadata: -{{- if .Values.prometheus.thanosIngress.annotations }} - annotations: - {{- tpl (toYaml .Values.prometheus.thanosIngress.annotations) . | nindent 4 }} -{{- end }} - name: {{ template "kube-prometheus-stack.fullname" . }}-thanos-gateway - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.prometheus.thanosIngress.labels }} -{{ toYaml .Values.prometheus.thanosIngress.labels | indent 4 }} -{{- end }} -spec: - {{- if $apiIsStable }} - {{- if .Values.prometheus.thanosIngress.ingressClassName }} - ingressClassName: {{ .Values.prometheus.thanosIngress.ingressClassName }} - {{- end }} - {{- end }} - rules: - {{- if .Values.prometheus.thanosIngress.hosts }} - {{- range $host := .Values.prometheus.thanosIngress.hosts }} - - host: {{ tpl $host $ }} - http: - paths: - {{- range $p := $paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ $serviceName }} - port: - number: {{ $thanosPort }} - {{- else }} - serviceName: {{ $serviceName }} - servicePort: {{ $thanosPort }} - {{- end }} - {{- end -}} - {{- end -}} - {{- else }} - - http: - paths: - {{- range $p := $paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ $serviceName }} - port: - number: {{ $thanosPort }} - {{- else }} - serviceName: {{ $serviceName }} - servicePort: {{ $thanosPort }} - {{- end }} - {{- end -}} - {{- end -}} - {{- if .Values.prometheus.thanosIngress.tls }} - tls: -{{ tpl (toYaml .Values.prometheus.thanosIngress.tls | indent 4) . }} - {{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingressperreplica.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingressperreplica.yaml deleted file mode 100644 index 1d76d135c8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/ingressperreplica.yaml +++ /dev/null @@ -1,67 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.servicePerReplica.enabled .Values.prometheus.ingressPerReplica.enabled }} -{{- $pathType := .Values.prometheus.ingressPerReplica.pathType | default "" }} -{{- $count := .Values.prometheus.prometheusSpec.replicas | int -}} -{{- $servicePort := .Values.prometheus.servicePerReplica.port -}} -{{- $ingressValues := .Values.prometheus.ingressPerReplica -}} -{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} -{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} -apiVersion: v1 -kind: List -metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-ingressperreplica - namespace: {{ template "kube-prometheus-stack.namespace" $ }} -items: -{{ range $i, $e := until $count }} - - kind: Ingress - apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" $ }} - metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-{{ $i }} - namespace: {{ template "kube-prometheus-stack.namespace" $ }} - labels: - app: {{ include "kube-prometheus-stack.name" $ }}-prometheus - {{ include "kube-prometheus-stack.labels" $ | indent 8 }} - {{- if $ingressValues.labels }} -{{ toYaml $ingressValues.labels | indent 8 }} - {{- end }} - {{- if $ingressValues.annotations }} - annotations: - {{- tpl (toYaml $ingressValues.annotations) $ | nindent 8 }} - {{- end }} - spec: - {{- if $apiIsStable }} - {{- if $ingressValues.ingressClassName }} - ingressClassName: {{ $ingressValues.ingressClassName }} - {{- end }} - {{- end }} - rules: - - host: {{ $ingressValues.hostPrefix }}-{{ $i }}.{{ $ingressValues.hostDomain }} - http: - paths: - {{- range $p := $ingressValues.paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-{{ $i }} - port: - number: {{ $servicePort }} - {{- else }} - serviceName: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-{{ $i }} - servicePort: {{ $servicePort }} - {{- end }} - {{- end -}} - {{- if or $ingressValues.tlsSecretName $ingressValues.tlsSecretPerReplica.enabled }} - tls: - - hosts: - - {{ $ingressValues.hostPrefix }}-{{ $i }}.{{ $ingressValues.hostDomain }} - {{- if $ingressValues.tlsSecretPerReplica.enabled }} - secretName: {{ $ingressValues.tlsSecretPerReplica.prefix }}-{{ $i }} - {{- else }} - secretName: {{ $ingressValues.tlsSecretName }} - {{- end }} - {{- end }} -{{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/networkpolicy.yaml deleted file mode 100644 index 1296a79063..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/networkpolicy.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if and .Values.prometheus.networkPolicy.enabled (eq .Values.prometheus.networkPolicy.flavor "kubernetes") }} -apiVersion: {{ template "kube-prometheus-stack.prometheus.networkPolicy.apiVersion" . }} -kind: NetworkPolicy -metadata: - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus - {{- include "kube-prometheus-stack.labels" . | nindent 4 }} - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - namespace: {{ template "kube-prometheus-stack.namespace" . }} -spec: - {{- if .Values.prometheus.networkPolicy.egress }} - egress: - {{- toYaml .Values.prometheus.networkPolicy.egress | nindent 4 }} - {{- end }} - {{- if .Values.prometheus.networkPolicy.ingress }} - ingress: - {{- toYaml .Values.prometheus.networkPolicy.ingress | nindent 4 }} - {{- end }} - policyTypes: - - Egress - - Ingress - podSelector: - {{- if .Values.prometheus.networkPolicy.podSelector }} - {{- toYaml .Values.prometheus.networkPolicy.podSelector | nindent 4 }} - {{- else }} - matchLabels: - {{- if .Values.prometheus.agentMode }} - app.kubernetes.io/name: prometheus-agent - {{- else }} - app.kubernetes.io/name: prometheus - {{- end }} - operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/nginx-config.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/nginx-config.yaml deleted file mode 100644 index e4d91f9a9e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/nginx-config.yaml +++ /dev/null @@ -1,68 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: prometheus-nginx-proxy-config - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.prometheus.annotations }} - annotations: -{{ toYaml .Values.prometheus.annotations | indent 4 }} -{{- end }} -data: - nginx.conf: |- - worker_processes auto; - error_log /dev/stdout warn; - pid /var/cache/nginx/nginx.pid; - - events { - worker_connections 1024; - } - - http { - include /etc/nginx/mime.types; - log_format main '[$time_local - $status] $remote_addr - $remote_user $request ($http_referer)'; - - proxy_connect_timeout 10; - proxy_read_timeout 180; - proxy_send_timeout 5; - proxy_buffering off; - proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my_zone:100m inactive=1d max_size=10g; - - server { - listen 8081; - access_log off; - - gzip on; - gzip_min_length 1k; - gzip_comp_level 2; - gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript image/jpeg image/gif image/png; - gzip_vary on; - gzip_disable "MSIE [1-6]\."; - - proxy_set_header Host $host; - - location / { - proxy_cache my_zone; - proxy_cache_valid 200 302 1d; - proxy_cache_valid 301 30d; - proxy_cache_valid any 5m; - proxy_cache_bypass $http_cache_control; - add_header X-Proxy-Cache $upstream_cache_status; - add_header Cache-Control "public"; - - proxy_pass http://localhost:9090/; - - sub_filter_once off; - sub_filter 'var PATH_PREFIX = "";' 'var PATH_PREFIX = ".";'; - - if ($request_filename ~ .*\.(?:js|css|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$) { - expires 90d; - } - - rewrite ^/k8s/clusters/.*/proxy(.*) /$1 break; - - } - } - } diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/podDisruptionBudget.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/podDisruptionBudget.yaml deleted file mode 100644 index 48f3f1f5a6..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/podDisruptionBudget.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.podDisruptionBudget.enabled }} -apiVersion: {{ include "kube-prometheus-stack.pdb.apiVersion" . }} -kind: PodDisruptionBudget -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - {{- if .Values.prometheus.podDisruptionBudget.minAvailable }} - minAvailable: {{ .Values.prometheus.podDisruptionBudget.minAvailable }} - {{- end }} - {{- if .Values.prometheus.podDisruptionBudget.maxUnavailable }} - maxUnavailable: {{ .Values.prometheus.podDisruptionBudget.maxUnavailable }} - {{- end }} - selector: - matchLabels: - {{- if .Values.prometheus.agentMode }} - app.kubernetes.io/name: prometheus-agent - {{- else }} - app.kubernetes.io/name: prometheus - {{- end }} - operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/podmonitors.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/podmonitors.yaml deleted file mode 100644 index 4e748c23b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/podmonitors.yaml +++ /dev/null @@ -1,38 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.additionalPodMonitors }} -apiVersion: v1 -kind: List -items: -{{- range .Values.prometheus.additionalPodMonitors }} - - apiVersion: monitoring.coreos.com/v1 - kind: PodMonitor - metadata: - name: {{ .name }} - namespace: {{ template "kube-prometheus-stack.namespace" $ }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-prometheus -{{ include "kube-prometheus-stack.labels" $ | indent 8 }} - {{- if .additionalLabels }} -{{ toYaml .additionalLabels | indent 8 }} - {{- end }} - spec: - {{- include "servicemonitor.scrapeLimits" . | nindent 6 }} - podMetricsEndpoints: -{{ toYaml .podMetricsEndpoints | indent 8 }} - {{- if .jobLabel }} - jobLabel: {{ .jobLabel }} - {{- end }} - {{- if .namespaceSelector }} - namespaceSelector: -{{ toYaml .namespaceSelector | indent 8 }} - {{- end }} - selector: -{{ toYaml .selector | indent 8 }} - {{- if .podTargetLabels }} - podTargetLabels: -{{ toYaml .podTargetLabels | indent 8 }} - {{- end }} - {{- if .sampleLimit }} - sampleLimit: {{ .sampleLimit }} - {{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/prometheus.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/prometheus.yaml deleted file mode 100644 index e668b40a9f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/prometheus.yaml +++ /dev/null @@ -1,481 +0,0 @@ -{{- if .Values.prometheus.enabled }} -{{- if .Values.prometheus.agentMode }} -apiVersion: monitoring.coreos.com/v1alpha1 -kind: PrometheusAgent -{{- else }} -apiVersion: monitoring.coreos.com/v1 -kind: Prometheus -{{- end }} -metadata: - name: {{ template "kube-prometheus-stack.prometheus.crname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.prometheus.annotations }} - annotations: -{{ toYaml .Values.prometheus.annotations | indent 4 }} -{{- end }} -spec: - automountServiceAccountToken: {{ .Values.prometheus.prometheusSpec.automountServiceAccountToken }} -{{- if and (not .Values.prometheus.agentMode) (or .Values.prometheus.prometheusSpec.alertingEndpoints .Values.alertmanager.enabled) }} - alerting: - alertmanagers: -{{- if .Values.prometheus.prometheusSpec.alertingEndpoints }} -{{ toYaml .Values.prometheus.prometheusSpec.alertingEndpoints | indent 6 }} -{{- else if .Values.alertmanager.enabled }} - - namespace: {{ template "kube-prometheus-stack.namespace" . }} - name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager - port: {{ .Values.alertmanager.alertmanagerSpec.portName }} - {{- if .Values.alertmanager.alertmanagerSpec.routePrefix }} - pathPrefix: "{{ .Values.alertmanager.alertmanagerSpec.routePrefix }}" - {{- end }} - {{- if .Values.alertmanager.alertmanagerSpec.scheme }} - scheme: {{ .Values.alertmanager.alertmanagerSpec.scheme }} - {{- end }} - {{- if .Values.alertmanager.alertmanagerSpec.tlsConfig }} - tlsConfig: -{{ toYaml .Values.alertmanager.alertmanagerSpec.tlsConfig | indent 10 }} - {{- end }} - apiVersion: {{ .Values.alertmanager.apiVersion }} -{{- end }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.apiserverConfig }} - apiserverConfig: -{{ toYaml .Values.prometheus.prometheusSpec.apiserverConfig | indent 4}} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.image }} - {{- $registry := include "monitoring_registry" . | default .Values.prometheus.prometheusSpec.image.registry -}} - {{- if and .Values.prometheus.prometheusSpec.image.tag .Values.prometheus.prometheusSpec.image.sha }} - image: "{{ $registry }}/{{ .Values.prometheus.prometheusSpec.image.repository }}:{{ .Values.prometheus.prometheusSpec.image.tag }}@sha256:{{ .Values.prometheus.prometheusSpec.image.sha }}" - {{- else if .Values.prometheus.prometheusSpec.image.sha }} - image: "{{ $registry }}/{{ .Values.prometheus.prometheusSpec.image.repository }}@sha256:{{ .Values.prometheus.prometheusSpec.image.sha }}" - {{- else if .Values.prometheus.prometheusSpec.image.tag }} - image: "{{ $registry }}/{{ .Values.prometheus.prometheusSpec.image.repository }}:{{ .Values.prometheus.prometheusSpec.image.tag }}" - {{- else }} - image: "{{ $registry }}/{{ .Values.prometheus.prometheusSpec.image.repository }}" - {{- end }} - version: {{ default .Values.prometheus.prometheusSpec.image.tag .Values.prometheus.prometheusSpec.version }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.additionalArgs }} - additionalArgs: -{{ toYaml .Values.prometheus.prometheusSpec.additionalArgs | indent 4}} -{{- end -}} -{{- if .Values.prometheus.prometheusSpec.externalLabels }} - externalLabels: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.externalLabels | indent 4) . }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.prometheusExternalLabelNameClear }} - prometheusExternalLabelName: "" -{{- else if .Values.prometheus.prometheusSpec.prometheusExternalLabelName }} - prometheusExternalLabelName: "{{ .Values.prometheus.prometheusSpec.prometheusExternalLabelName }}" -{{- end }} -{{- if .Values.prometheus.prometheusSpec.replicaExternalLabelNameClear }} - replicaExternalLabelName: "" -{{- else if .Values.prometheus.prometheusSpec.replicaExternalLabelName }} - replicaExternalLabelName: "{{ .Values.prometheus.prometheusSpec.replicaExternalLabelName }}" -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enableRemoteWriteReceiver }} - enableRemoteWriteReceiver: {{ .Values.prometheus.prometheusSpec.enableRemoteWriteReceiver }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.externalUrl }} - externalUrl: "{{ tpl .Values.prometheus.prometheusSpec.externalUrl . }}" -{{- else if and .Values.prometheus.ingress.enabled .Values.prometheus.ingress.hosts }} - externalUrl: "http://{{ tpl (index .Values.prometheus.ingress.hosts 0) . }}{{ .Values.prometheus.prometheusSpec.routePrefix }}" -{{- else if not (or (kindIs "invalid" .Values.global.cattle.url) (kindIs "invalid" .Values.global.cattle.clusterId)) }} - externalUrl: "{{ .Values.global.cattle.url }}/k8s/clusters/{{ .Values.global.cattle.clusterId }}/api/v1/namespaces/{{ template "kube-prometheus-stack.namespace" . }}/services/http:{{ template "kube-prometheus-stack.fullname" . }}-prometheus:{{ .Values.prometheus.service.port }}/proxy" -{{- else }} - externalUrl: http://{{ template "kube-prometheus-stack.fullname" . }}-prometheus.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.prometheus.service.port }} -{{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 4 }} -{{- if .Values.prometheus.prometheusSpec.nodeSelector }} -{{ toYaml .Values.prometheus.prometheusSpec.nodeSelector | indent 4 }} -{{- end }} - paused: {{ .Values.prometheus.prometheusSpec.paused }} - replicas: {{ .Values.prometheus.prometheusSpec.replicas }} - shards: {{ .Values.prometheus.prometheusSpec.shards }} - logLevel: {{ .Values.prometheus.prometheusSpec.logLevel }} - logFormat: {{ .Values.prometheus.prometheusSpec.logFormat }} - listenLocal: {{ .Values.prometheus.prometheusSpec.listenLocal }} -{{- if not .Values.prometheus.agentMode }} - enableAdminAPI: {{ .Values.prometheus.prometheusSpec.enableAdminAPI }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.web }} - web: -{{ toYaml .Values.prometheus.prometheusSpec.web | indent 4 }} -{{- end }} -{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.exemplars }} - exemplars: - {{- toYaml .Values.prometheus.prometheusSpec.exemplars | nindent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enableFeatures }} - enableFeatures: -{{- range $enableFeatures := .Values.prometheus.prometheusSpec.enableFeatures }} - - {{ tpl $enableFeatures $ }} -{{- end }} -{{- end }} -{{- with .Values.prometheus.prometheusSpec.scrapeClasses }} - scrapeClasses: - {{- tpl (toYaml . | nindent 4) $ }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.scrapeInterval }} - scrapeInterval: {{ .Values.prometheus.prometheusSpec.scrapeInterval }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.scrapeTimeout }} - scrapeTimeout: {{ .Values.prometheus.prometheusSpec.scrapeTimeout }} -{{- end }} -{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.evaluationInterval }} - evaluationInterval: {{ .Values.prometheus.prometheusSpec.evaluationInterval }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.resources }} - resources: -{{ toYaml .Values.prometheus.prometheusSpec.resources | indent 4 }} -{{- end }} -{{- if not .Values.prometheus.agentMode }} - retention: {{ .Values.prometheus.prometheusSpec.retention | quote }} -{{- if .Values.prometheus.prometheusSpec.retentionSize }} - retentionSize: {{ .Values.prometheus.prometheusSpec.retentionSize | quote }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.tsdb }} - tsdb: - {{- if .Values.prometheus.prometheusSpec.tsdb.outOfOrderTimeWindow }} - outOfOrderTimeWindow: {{ .Values.prometheus.prometheusSpec.tsdb.outOfOrderTimeWindow }} - {{- end }} -{{- end }} -{{- end }} -{{- if eq .Values.prometheus.prometheusSpec.walCompression false }} - walCompression: false -{{ else }} - walCompression: true -{{- end }} -{{- if .Values.prometheus.prometheusSpec.routePrefix }} - routePrefix: {{ .Values.prometheus.prometheusSpec.routePrefix | quote }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.secrets }} - secrets: -{{ toYaml .Values.prometheus.prometheusSpec.secrets | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.configMaps }} - configMaps: -{{ toYaml .Values.prometheus.prometheusSpec.configMaps | indent 4 }} -{{- end }} - serviceAccountName: {{ template "kube-prometheus-stack.prometheus.serviceAccountName" . }} -{{- if .Values.prometheus.prometheusSpec.serviceMonitorSelector }} - serviceMonitorSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.serviceMonitorSelector | indent 4) . }} -{{ else if .Values.prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues }} - serviceMonitorSelector: - matchLabels: - release: {{ $.Release.Name | quote }} -{{ else }} - serviceMonitorSelector: {} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.serviceMonitorNamespaceSelector }} - serviceMonitorNamespaceSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.serviceMonitorNamespaceSelector | indent 4) . }} -{{ else }} - serviceMonitorNamespaceSelector: {} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.podMonitorSelector }} - podMonitorSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.podMonitorSelector | indent 4) . }} -{{ else if .Values.prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues }} - podMonitorSelector: - matchLabels: - release: {{ $.Release.Name | quote }} -{{ else }} - podMonitorSelector: {} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.podMonitorNamespaceSelector }} - podMonitorNamespaceSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.podMonitorNamespaceSelector | indent 4) . }} -{{ else }} - podMonitorNamespaceSelector: {} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.probeSelector }} - probeSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.probeSelector | indent 4) . }} -{{ else if .Values.prometheus.prometheusSpec.probeSelectorNilUsesHelmValues }} - probeSelector: - matchLabels: - release: {{ $.Release.Name | quote }} -{{ else }} - probeSelector: {} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.probeNamespaceSelector }} - probeNamespaceSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.probeNamespaceSelector | indent 4) . }} -{{ else }} - probeNamespaceSelector: {} -{{- end }} -{{- if and (not .Values.prometheus.agentMode) (or .Values.prometheus.prometheusSpec.remoteRead .Values.prometheus.prometheusSpec.additionalRemoteRead) }} - remoteRead: -{{- if .Values.prometheus.prometheusSpec.remoteRead }} -{{ tpl (toYaml .Values.prometheus.prometheusSpec.remoteRead | indent 4) . }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.additionalRemoteRead }} -{{ toYaml .Values.prometheus.prometheusSpec.additionalRemoteRead | indent 4 }} -{{- end }} -{{- end }} -{{- if (or .Values.prometheus.prometheusSpec.remoteWrite .Values.prometheus.prometheusSpec.additionalRemoteWrite) }} - remoteWrite: -{{- if .Values.prometheus.prometheusSpec.remoteWrite }} -{{ tpl (toYaml .Values.prometheus.prometheusSpec.remoteWrite | indent 4) . }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.additionalRemoteWrite }} -{{ toYaml .Values.prometheus.prometheusSpec.additionalRemoteWrite | indent 4 }} -{{- end }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.securityContext }} - securityContext: -{{ toYaml .Values.prometheus.prometheusSpec.securityContext | indent 4 }} -{{- end }} -{{- if not .Values.prometheus.agentMode }} -{{- if .Values.prometheus.prometheusSpec.ruleNamespaceSelector }} - ruleNamespaceSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.ruleNamespaceSelector | indent 4) . }} -{{ else }} - ruleNamespaceSelector: {} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.ruleSelector }} - ruleSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.ruleSelector | indent 4) . }} -{{- else if .Values.prometheus.prometheusSpec.ruleSelectorNilUsesHelmValues }} - ruleSelector: - matchLabels: - release: {{ $.Release.Name | quote }} -{{ else }} - ruleSelector: {} -{{- end }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.scrapeConfigSelector }} - scrapeConfigSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.scrapeConfigSelector | indent 4) . }} -{{ else if .Values.prometheus.prometheusSpec.scrapeConfigSelectorNilUsesHelmValues }} - scrapeConfigSelector: - matchLabels: - release: {{ $.Release.Name | quote }} -{{ else }} - scrapeConfigSelector: {} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.scrapeConfigNamespaceSelector }} - scrapeConfigNamespaceSelector: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.scrapeConfigNamespaceSelector | indent 4) . }} -{{ else }} - scrapeConfigNamespaceSelector: {} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.storageSpec }} - storage: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.storageSpec | indent 4) . }} -{{- end }} -{{- with .Values.prometheus.prometheusSpec.persistentVolumeClaimRetentionPolicy }} - persistentVolumeClaimRetentionPolicy: - {{- toYaml . | nindent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.podMetadata }} - podMetadata: -{{ tpl (toYaml .Values.prometheus.prometheusSpec.podMetadata | indent 4) . }} -{{- end }} -{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.query }} - query: -{{ toYaml .Values.prometheus.prometheusSpec.query | indent 4}} -{{- end }} -{{- if or .Values.prometheus.prometheusSpec.podAntiAffinity .Values.prometheus.prometheusSpec.affinity }} - affinity: -{{- if .Values.prometheus.prometheusSpec.affinity }} -{{ toYaml .Values.prometheus.prometheusSpec.affinity | indent 4 }} -{{- end }} -{{- if eq .Values.prometheus.prometheusSpec.podAntiAffinity "hard" }} - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - topologyKey: {{ .Values.prometheus.prometheusSpec.podAntiAffinityTopologyKey }} - labelSelector: - matchExpressions: - - {key: app.kubernetes.io/name, operator: In, values: [prometheus]} - - {key: prometheus, operator: In, values: [{{ template "kube-prometheus-stack.prometheus.crname" . }}]} -{{- else if eq .Values.prometheus.prometheusSpec.podAntiAffinity "soft" }} - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - topologyKey: {{ .Values.prometheus.prometheusSpec.podAntiAffinityTopologyKey }} - labelSelector: - matchExpressions: - - {key: app.kubernetes.io/name, operator: In, values: [prometheus]} - - {key: prometheus, operator: In, values: [{{ template "kube-prometheus-stack.prometheus.crname" . }}]} -{{- end }} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 4 }} -{{- if .Values.prometheus.prometheusSpec.tolerations }} -{{ toYaml .Values.prometheus.prometheusSpec.tolerations | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.topologySpreadConstraints }} - topologySpreadConstraints: -{{ toYaml .Values.prometheus.prometheusSpec.topologySpreadConstraints | indent 4 }} -{{- end }} -{{- if .Values.global.imagePullSecrets }} - imagePullSecrets: -{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.additionalScrapeConfigs }} - additionalScrapeConfigs: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-scrape-confg - key: additional-scrape-configs.yaml -{{- end }} -{{- if .Values.prometheus.prometheusSpec.additionalScrapeConfigsSecret.enabled }} - additionalScrapeConfigs: - name: {{ .Values.prometheus.prometheusSpec.additionalScrapeConfigsSecret.name }} - key: {{ .Values.prometheus.prometheusSpec.additionalScrapeConfigsSecret.key }} -{{- end }} -{{- if not .Values.prometheus.agentMode }} -{{- if or .Values.prometheus.prometheusSpec.additionalAlertManagerConfigs .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret }} - additionalAlertManagerConfigs: -{{- if .Values.prometheus.prometheusSpec.additionalAlertManagerConfigs }} - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-am-confg - key: additional-alertmanager-configs.yaml -{{- end }} -{{- if .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret }} - name: {{ .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret.name }} - key: {{ .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret.key }} - {{- if hasKey .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret "optional" }} - optional: {{ .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret.optional }} - {{- end }} -{{- end }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigs }} - additionalAlertRelabelConfigs: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-am-relabel-confg - key: additional-alert-relabel-configs.yaml -{{- end }} -{{- if .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigsSecret }} - additionalAlertRelabelConfigs: - name: {{ .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigsSecret.name }} - key: {{ .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigsSecret.key }} -{{- end }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.containers }} - containers: -{{ tpl .Values.prometheus.prometheusSpec.containers $ | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.initContainers }} - initContainers: -{{ toYaml .Values.prometheus.prometheusSpec.initContainers | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.priorityClassName }} - priorityClassName: {{ .Values.prometheus.prometheusSpec.priorityClassName }} -{{- end }} -{{- if not .Values.prometheus.agentMode }} -{{- if .Values.prometheus.prometheusSpec.thanos }} - thanos: -{{- with (omit .Values.prometheus.prometheusSpec.thanos "objectStorageConfig")}} -{{ toYaml . | indent 4 }} -{{- end }} -{{- if ((.Values.prometheus.prometheusSpec.thanos.objectStorageConfig).existingSecret) }} - objectStorageConfig: - key: "{{.Values.prometheus.prometheusSpec.thanos.objectStorageConfig.existingSecret.key }}" - name: "{{.Values.prometheus.prometheusSpec.thanos.objectStorageConfig.existingSecret.name }}" -{{- else if ((.Values.prometheus.prometheusSpec.thanos.objectStorageConfig).secret) }} - objectStorageConfig: - key: object-storage-configs.yaml - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus -{{- end }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.disableCompaction }} - disableCompaction: {{ .Values.prometheus.prometheusSpec.disableCompaction }} -{{- end }} -{{- end }} - portName: {{ .Values.prometheus.prometheusSpec.portName }} -{{- if .Values.prometheus.prometheusSpec.volumes }} - volumes: -{{ toYaml .Values.prometheus.prometheusSpec.volumes | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.volumeMounts }} - volumeMounts: -{{ toYaml .Values.prometheus.prometheusSpec.volumeMounts | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.arbitraryFSAccessThroughSMs }} - arbitraryFSAccessThroughSMs: -{{ toYaml .Values.prometheus.prometheusSpec.arbitraryFSAccessThroughSMs | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.overrideHonorLabels }} - overrideHonorLabels: {{ .Values.prometheus.prometheusSpec.overrideHonorLabels }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.overrideHonorTimestamps }} - overrideHonorTimestamps: {{ .Values.prometheus.prometheusSpec.overrideHonorTimestamps }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} - ignoreNamespaceSelectors: {{ .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enforcedNamespaceLabel }} - enforcedNamespaceLabel: {{ .Values.prometheus.prometheusSpec.enforcedNamespaceLabel }} -{{- $prometheusDefaultRulesExcludedFromEnforce := (include "rules.names" .) | fromYaml }} -{{- if not .Values.prometheus.agentMode }} - prometheusRulesExcludedFromEnforce: -{{- range $prometheusDefaultRulesExcludedFromEnforce.rules }} - - ruleNamespace: "{{ template "kube-prometheus-stack.namespace" $ }}" - ruleName: "{{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) . | trunc 63 | trimSuffix "-" }}" -{{- end }} -{{- if .Values.prometheus.prometheusSpec.prometheusRulesExcludedFromEnforce }} -{{ toYaml .Values.prometheus.prometheusSpec.prometheusRulesExcludedFromEnforce | indent 4 }} -{{- end }} -{{- end }} - excludedFromEnforcement: -{{- range $prometheusDefaultRulesExcludedFromEnforce.rules }} - - group: monitoring.coreos.com - resource: prometheusrules - namespace: "{{ template "kube-prometheus-stack.namespace" $ }}" - name: "{{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) . | trunc 63 | trimSuffix "-" }}" -{{- end }} -{{- if .Values.prometheus.prometheusSpec.excludedFromEnforcement }} -{{ tpl (toYaml .Values.prometheus.prometheusSpec.excludedFromEnforcement | indent 4) . }} -{{- end }} -{{- end }} -{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.queryLogFile }} - queryLogFile: {{ .Values.prometheus.prometheusSpec.queryLogFile }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.sampleLimit }} - sampleLimit: {{ .Values.prometheus.prometheusSpec.sampleLimit }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enforcedKeepDroppedTargets }} - enforcedKeepDroppedTargets: {{ .Values.prometheus.prometheusSpec.enforcedKeepDroppedTargets }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enforcedSampleLimit }} - enforcedSampleLimit: {{ .Values.prometheus.prometheusSpec.enforcedSampleLimit }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enforcedTargetLimit }} - enforcedTargetLimit: {{ .Values.prometheus.prometheusSpec.enforcedTargetLimit }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enforcedLabelLimit }} - enforcedLabelLimit: {{ .Values.prometheus.prometheusSpec.enforcedLabelLimit }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enforcedLabelNameLengthLimit }} - enforcedLabelNameLengthLimit: {{ .Values.prometheus.prometheusSpec.enforcedLabelNameLengthLimit }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.enforcedLabelValueLengthLimit}} - enforcedLabelValueLengthLimit: {{ .Values.prometheus.prometheusSpec.enforcedLabelValueLengthLimit }} -{{- end }} -{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.allowOverlappingBlocks }} - allowOverlappingBlocks: {{ .Values.prometheus.prometheusSpec.allowOverlappingBlocks }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.minReadySeconds }} - minReadySeconds: {{ .Values.prometheus.prometheusSpec.minReadySeconds }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.maximumStartupDurationSeconds }} - maximumStartupDurationSeconds: {{ .Values.prometheus.prometheusSpec.maximumStartupDurationSeconds }} -{{- end }} - hostNetwork: {{ .Values.prometheus.prometheusSpec.hostNetwork }} -{{- if .Values.prometheus.prometheusSpec.hostAliases }} - hostAliases: -{{ toYaml .Values.prometheus.prometheusSpec.hostAliases | indent 4 }} -{{- end }} -{{- if .Values.prometheus.prometheusSpec.tracingConfig }} - tracingConfig: -{{ toYaml .Values.prometheus.prometheusSpec.tracingConfig | indent 4 }} -{{- end }} -{{- with .Values.prometheus.prometheusSpec.additionalConfig }} - {{- tpl (toYaml .) $ | nindent 2 }} -{{- end }} -{{- with .Values.prometheus.prometheusSpec.additionalConfigString }} - {{- tpl . $ | nindent 2 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp-clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp-clusterrole.yaml deleted file mode 100644 index 872feb6066..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp-clusterrole.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-psp - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -rules: -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} -- apiGroups: ['policy'] -{{- else }} -- apiGroups: ['extensions'] -{{- end }} - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - {{ template "kube-prometheus-stack.fullname" . }}-prometheus -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp-clusterrolebinding.yaml deleted file mode 100644 index 50e3617704..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp-clusterrolebinding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-psp - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-psp -subjects: - - kind: ServiceAccount - name: {{ template "kube-prometheus-stack.prometheus.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp.yaml deleted file mode 100644 index b53808daa5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/psp.yaml +++ /dev/null @@ -1,58 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} -{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{- if .Values.global.rbac.pspAnnotations }} - annotations: -{{ toYaml .Values.global.rbac.pspAnnotations | indent 4 }} -{{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - privileged: false - # Allow core volume types. - volumes: - - 'configMap' - - 'emptyDir' - - 'projected' - - 'secret' - - 'downwardAPI' - - 'persistentVolumeClaim' -{{- if .Values.prometheus.podSecurityPolicy.volumes }} -{{ toYaml .Values.prometheus.podSecurityPolicy.volumes | indent 4 }} -{{- end }} - hostNetwork: false - hostIPC: false - hostPID: false - runAsUser: - # Permits the container to run with root privileges as well. - rule: 'RunAsAny' - seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - # Allow adding the root group. - - min: 0 - max: 65535 - readOnlyRootFilesystem: false -{{- if .Values.prometheus.podSecurityPolicy.allowedCapabilities }} - allowedCapabilities: -{{ toYaml .Values.prometheus.podSecurityPolicy.allowedCapabilities | indent 4 }} -{{- end }} -{{- if .Values.prometheus.podSecurityPolicy.allowedHostPaths }} - allowedHostPaths: -{{ toYaml .Values.prometheus.podSecurityPolicy.allowedHostPaths | indent 4 }} -{{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/alertmanager.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/alertmanager.rules.yaml deleted file mode 100644 index 2d432c8f3a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/alertmanager.rules.yaml +++ /dev/null @@ -1,305 +0,0 @@ -{{- /* -Generated from 'alertmanager.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.alertmanager }} -{{- $alertmanagerJob := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "alertmanager" }} -{{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} -{{- if and .Values.alertmanager.enabled .Values.alertmanager.serviceMonitor.selfMonitor }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "alertmanager.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: alertmanager.rules - rules: -{{- if not (.Values.defaultRules.disabled.AlertmanagerFailedReload | default false) }} - - alert: AlertmanagerFailedReload - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} -{{- end }} - description: Configuration has failed to load for {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod{{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerfailedreload - summary: Reloading an Alertmanager configuration has failed. - expr: |- - # Without max_over_time, failed scrapes could create false negatives, see - # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. - max_over_time(alertmanager_config_last_reload_successful{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) == 0 - for: {{ dig "AlertmanagerFailedReload" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "AlertmanagerFailedReload" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.AlertmanagerMembersInconsistent | default false) }} - - alert: AlertmanagerMembersInconsistent - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} -{{- end }} - description: Alertmanager {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod{{`}}`}} has only found {{`{{`}} $value {{`}}`}} members of the {{`{{`}}$labels.job{{`}}`}} cluster. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagermembersinconsistent - summary: A member of an Alertmanager cluster has not found all other cluster members. - expr: |- - # Without max_over_time, failed scrapes could create false negatives, see - # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. - max_over_time(alertmanager_cluster_members{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) - < on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) group_left - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) (max_over_time(alertmanager_cluster_members{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m])) - for: {{ dig "AlertmanagerMembersInconsistent" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "AlertmanagerMembersInconsistent" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.AlertmanagerFailedToSendAlerts | default false) }} - - alert: AlertmanagerFailedToSendAlerts - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} -{{- end }} - description: Alertmanager {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod{{`}}`}} failed to send {{`{{`}} $value | humanizePercentage {{`}}`}} of notifications to {{`{{`}} $labels.integration {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerfailedtosendalerts - summary: An Alertmanager instance failed to send notifications. - expr: |- - ( - rate(alertmanager_notifications_failed_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) - / - ignoring (reason) group_left rate(alertmanager_notifications_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) - ) - > 0.01 - for: {{ dig "AlertmanagerFailedToSendAlerts" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "AlertmanagerFailedToSendAlerts" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.AlertmanagerClusterFailedToSendAlerts | default false) }} - - alert: AlertmanagerClusterFailedToSendAlerts - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} -{{- end }} - description: The minimum notification failure rate to {{`{{`}} $labels.integration {{`}}`}} sent from any instance in the {{`{{`}}$labels.job{{`}}`}} cluster is {{`{{`}} $value | humanizePercentage {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerclusterfailedtosendalerts - summary: All Alertmanager instances in a cluster failed to send notifications to a critical integration. - expr: |- - min by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service, integration) ( - rate(alertmanager_notifications_failed_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}", integration=~`.*`}[5m]) - / - ignoring (reason) group_left rate(alertmanager_notifications_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}", integration=~`.*`}[5m]) - ) - > 0.01 - for: {{ dig "AlertmanagerClusterFailedToSendAlerts" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "AlertmanagerClusterFailedToSendAlerts" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.AlertmanagerClusterFailedToSendAlerts | default false) }} - - alert: AlertmanagerClusterFailedToSendAlerts - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} -{{- end }} - description: The minimum notification failure rate to {{`{{`}} $labels.integration {{`}}`}} sent from any instance in the {{`{{`}}$labels.job{{`}}`}} cluster is {{`{{`}} $value | humanizePercentage {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerclusterfailedtosendalerts - summary: All Alertmanager instances in a cluster failed to send notifications to a non-critical integration. - expr: |- - min by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service, integration) ( - rate(alertmanager_notifications_failed_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}", integration!~`.*`}[5m]) - / - ignoring (reason) group_left rate(alertmanager_notifications_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}", integration!~`.*`}[5m]) - ) - > 0.01 - for: {{ dig "AlertmanagerClusterFailedToSendAlerts" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "AlertmanagerClusterFailedToSendAlerts" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.AlertmanagerConfigInconsistent | default false) }} - - alert: AlertmanagerConfigInconsistent - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} -{{- end }} - description: Alertmanager instances within the {{`{{`}}$labels.job{{`}}`}} cluster have different configurations. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerconfiginconsistent - summary: Alertmanager instances within the same cluster have different configurations. - expr: |- - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( - count_values by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ("config_hash", alertmanager_config_hash{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}) - ) - != 1 - for: {{ dig "AlertmanagerConfigInconsistent" "for" "20m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "AlertmanagerConfigInconsistent" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.AlertmanagerClusterDown | default false) }} - - alert: AlertmanagerClusterDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} -{{- end }} - description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of Alertmanager instances within the {{`{{`}}$labels.job{{`}}`}} cluster have been up for less than half of the last 5m.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerclusterdown - summary: Half or more of the Alertmanager instances within the same cluster are down. - expr: |- - ( - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( - avg_over_time(up{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) < 0.5 - ) - / - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( - up{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"} - ) - ) - >= 0.5 - for: {{ dig "AlertmanagerClusterDown" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "AlertmanagerClusterDown" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.AlertmanagerClusterCrashlooping | default false) }} - - alert: AlertmanagerClusterCrashlooping - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} -{{- end }} - description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of Alertmanager instances within the {{`{{`}}$labels.job{{`}}`}} cluster have restarted at least 5 times in the last 10m.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerclustercrashlooping - summary: Half or more of the Alertmanager instances within the same cluster are crashlooping. - expr: |- - ( - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( - changes(process_start_time_seconds{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[10m]) > 4 - ) - / - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( - up{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"} - ) - ) - >= 0.5 - for: {{ dig "AlertmanagerClusterCrashlooping" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "AlertmanagerClusterCrashlooping" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/config-reloaders.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/config-reloaders.yaml deleted file mode 100644 index 9f554c022f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/config-reloaders.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- /* -Generated from 'config-reloaders' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.configReloaders }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "config-reloaders" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: config-reloaders - rules: -{{- if not (.Values.defaultRules.disabled.ConfigReloaderSidecarErrors | default false) }} - - alert: ConfigReloaderSidecarErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.configReloaders }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.configReloaders | indent 8 }} -{{- end }} - description: 'Errors encountered while the {{`{{`}}$labels.pod{{`}}`}} config-reloader sidecar attempts to sync config in {{`{{`}}$labels.namespace{{`}}`}} namespace. - - As a result, configuration for service running in {{`{{`}}$labels.pod{{`}}`}} may be stale and cannot be updated anymore.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/configreloadersidecarerrors - summary: config-reloader sidecar has not had a successful reload for 10m - expr: max_over_time(reloader_last_reload_successful{namespace=~".+"}[5m]) == 0 - for: {{ dig "ConfigReloaderSidecarErrors" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "ConfigReloaderSidecarErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.configReloaders }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.configReloaders }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/etcd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/etcd.yaml deleted file mode 100644 index a1d7a508f8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/etcd.yaml +++ /dev/null @@ -1,461 +0,0 @@ -{{- /* -Generated from 'etcd' group from https://github.com/etcd-io/etcd.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.etcd }} -{{- if (include "exporter.kubeEtcd.enabled" .)}} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "etcd" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: etcd - rules: -{{- if not (.Values.defaultRules.disabled.etcdMembersDown | default false) }} - - alert: etcdMembersDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": members are down ({{`{{`}} $value {{`}}`}}).' - summary: etcd cluster members are down. - expr: |- - max without (endpoint) ( - sum without (instance) (up{job=~".*etcd.*"} == bool 0) - or - count without (To) ( - sum without (instance) (rate(etcd_network_peer_sent_failures_total{job=~".*etcd.*"}[120s])) > 0.01 - ) - ) - > 0 - for: {{ dig "etcdMembersDown" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdMembersDown" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdInsufficientMembers | default false) }} - - alert: etcdInsufficientMembers - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": insufficient members ({{`{{`}} $value {{`}}`}}).' - summary: etcd cluster has insufficient number of members. - expr: sum(up{job=~".*etcd.*"} == bool 1) without (instance) < ((count(up{job=~".*etcd.*"}) without (instance) + 1) / 2) - for: {{ dig "etcdInsufficientMembers" "for" "3m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdInsufficientMembers" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdNoLeader | default false) }} - - alert: etcdNoLeader - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": member {{`{{`}} $labels.instance {{`}}`}} has no leader.' - summary: etcd cluster has no leader. - expr: etcd_server_has_leader{job=~".*etcd.*"} == 0 - for: {{ dig "etcdNoLeader" "for" "1m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdNoLeader" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdHighNumberOfLeaderChanges | default false) }} - - alert: etcdHighNumberOfLeaderChanges - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": {{`{{`}} $value {{`}}`}} leader changes within the last 15 minutes. Frequent elections may be a sign of insufficient resources, high network latency, or disruptions by other components and should be investigated.' - summary: etcd cluster has high number of leader changes. - expr: increase((max without (instance) (etcd_server_leader_changes_seen_total{job=~".*etcd.*"}) or 0*absent(etcd_server_leader_changes_seen_total{job=~".*etcd.*"}))[15m:1m]) >= 4 - for: {{ dig "etcdHighNumberOfLeaderChanges" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdHighNumberOfLeaderChanges" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdHighNumberOfFailedGRPCRequests | default false) }} - - alert: etcdHighNumberOfFailedGRPCRequests - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": {{`{{`}} $value {{`}}`}}% of requests for {{`{{`}} $labels.grpc_method {{`}}`}} failed on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' - summary: etcd cluster has high number of failed grpc requests. - expr: |- - 100 * sum(rate(grpc_server_handled_total{job=~".*etcd.*", grpc_code=~"Unknown|FailedPrecondition|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded"}[5m])) without (grpc_type, grpc_code) - / - sum(rate(grpc_server_handled_total{job=~".*etcd.*"}[5m])) without (grpc_type, grpc_code) - > 1 - for: {{ dig "etcdHighNumberOfFailedGRPCRequests" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdHighNumberOfFailedGRPCRequests" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdHighNumberOfFailedGRPCRequests | default false) }} - - alert: etcdHighNumberOfFailedGRPCRequests - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": {{`{{`}} $value {{`}}`}}% of requests for {{`{{`}} $labels.grpc_method {{`}}`}} failed on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' - summary: etcd cluster has high number of failed grpc requests. - expr: |- - 100 * sum(rate(grpc_server_handled_total{job=~".*etcd.*", grpc_code=~"Unknown|FailedPrecondition|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded"}[5m])) without (grpc_type, grpc_code) - / - sum(rate(grpc_server_handled_total{job=~".*etcd.*"}[5m])) without (grpc_type, grpc_code) - > 5 - for: {{ dig "etcdHighNumberOfFailedGRPCRequests" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdHighNumberOfFailedGRPCRequests" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdGRPCRequestsSlow | default false) }} - - alert: etcdGRPCRequestsSlow - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": 99th percentile of gRPC requests is {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}} for {{`{{`}} $labels.grpc_method {{`}}`}} method.' - summary: etcd grpc requests are slow - expr: |- - histogram_quantile(0.99, sum(rate(grpc_server_handling_seconds_bucket{job=~".*etcd.*", grpc_method!="Defragment", grpc_type="unary"}[5m])) without(grpc_type)) - > 0.15 - for: {{ dig "etcdGRPCRequestsSlow" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdGRPCRequestsSlow" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdMemberCommunicationSlow | default false) }} - - alert: etcdMemberCommunicationSlow - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": member communication with {{`{{`}} $labels.To {{`}}`}} is taking {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' - summary: etcd cluster member communication is slow. - expr: |- - histogram_quantile(0.99, rate(etcd_network_peer_round_trip_time_seconds_bucket{job=~".*etcd.*"}[5m])) - > 0.15 - for: {{ dig "etcdMemberCommunicationSlow" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdMemberCommunicationSlow" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdHighNumberOfFailedProposals | default false) }} - - alert: etcdHighNumberOfFailedProposals - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": {{`{{`}} $value {{`}}`}} proposal failures within the last 30 minutes on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' - summary: etcd cluster has high number of proposal failures. - expr: rate(etcd_server_proposals_failed_total{job=~".*etcd.*"}[15m]) > 5 - for: {{ dig "etcdHighNumberOfFailedProposals" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdHighNumberOfFailedProposals" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdHighFsyncDurations | default false) }} - - alert: etcdHighFsyncDurations - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": 99th percentile fsync durations are {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' - summary: etcd cluster 99th percentile fsync durations are too high. - expr: |- - histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket{job=~".*etcd.*"}[5m])) - > 0.5 - for: {{ dig "etcdHighFsyncDurations" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdHighFsyncDurations" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdHighFsyncDurations | default false) }} - - alert: etcdHighFsyncDurations - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": 99th percentile fsync durations are {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' - summary: etcd cluster 99th percentile fsync durations are too high. - expr: |- - histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket{job=~".*etcd.*"}[5m])) - > 1 - for: {{ dig "etcdHighFsyncDurations" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdHighFsyncDurations" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdHighCommitDurations | default false) }} - - alert: etcdHighCommitDurations - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": 99th percentile commit durations {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' - summary: etcd cluster 99th percentile commit durations are too high. - expr: |- - histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket{job=~".*etcd.*"}[5m])) - > 0.25 - for: {{ dig "etcdHighCommitDurations" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdHighCommitDurations" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdDatabaseQuotaLowSpace | default false) }} - - alert: etcdDatabaseQuotaLowSpace - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": database size exceeds the defined quota on etcd instance {{`{{`}} $labels.instance {{`}}`}}, please defrag or increase the quota as the writes to etcd will be disabled when it is full.' - summary: etcd cluster database is running full. - expr: (last_over_time(etcd_mvcc_db_total_size_in_bytes{job=~".*etcd.*"}[5m]) / last_over_time(etcd_server_quota_backend_bytes{job=~".*etcd.*"}[5m]))*100 > 95 - for: {{ dig "etcdDatabaseQuotaLowSpace" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdDatabaseQuotaLowSpace" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdExcessiveDatabaseGrowth | default false) }} - - alert: etcdExcessiveDatabaseGrowth - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": Predicting running out of disk space in the next four hours, based on write observations within the past four hours on etcd instance {{`{{`}} $labels.instance {{`}}`}}, please check as it might be disruptive.' - summary: etcd cluster database growing very fast. - expr: predict_linear(etcd_mvcc_db_total_size_in_bytes{job=~".*etcd.*"}[4h], 4*60*60) > etcd_server_quota_backend_bytes{job=~".*etcd.*"} - for: {{ dig "etcdExcessiveDatabaseGrowth" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdExcessiveDatabaseGrowth" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.etcdDatabaseHighFragmentationRatio | default false) }} - - alert: etcdDatabaseHighFragmentationRatio - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} -{{- end }} - description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": database size in use on instance {{`{{`}} $labels.instance {{`}}`}} is {{`{{`}} $value | humanizePercentage {{`}}`}} of the actual allocated disk space, please run defragmentation (e.g. etcdctl defrag) to retrieve the unused fragmented disk space.' - runbook_url: https://etcd.io/docs/v3.5/op-guide/maintenance/#defragmentation - summary: etcd database size in use is less than 50% of the actual allocated storage. - expr: (last_over_time(etcd_mvcc_db_total_size_in_use_in_bytes{job=~".*etcd.*"}[5m]) / last_over_time(etcd_mvcc_db_total_size_in_bytes{job=~".*etcd.*"}[5m])) < 0.5 and etcd_mvcc_db_total_size_in_use_in_bytes{job=~".*etcd.*"} > 104857600 - for: {{ dig "etcdDatabaseHighFragmentationRatio" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "etcdDatabaseHighFragmentationRatio" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/general.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/general.rules.yaml deleted file mode 100644 index 6324228838..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/general.rules.yaml +++ /dev/null @@ -1,125 +0,0 @@ -{{- /* -Generated from 'general.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.general }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "general.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: general.rules - rules: -{{- if not (.Values.defaultRules.disabled.TargetDown | default false) }} - - alert: TargetDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.general }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.general | indent 8 }} -{{- end }} - description: '{{`{{`}} printf "%.4g" $value {{`}}`}}% of the {{`{{`}} $labels.job {{`}}`}}/{{`{{`}} $labels.service {{`}}`}} targets in {{`{{`}} $labels.namespace {{`}}`}} namespace are down.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/general/targetdown - summary: One or more targets are unreachable. - expr: 100 * (count(up == 0) BY (cluster, job, namespace, service) / count(up) BY (cluster, job, namespace, service)) > 10 - for: {{ dig "TargetDown" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "TargetDown" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.general }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.general }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.Watchdog | default false) }} - - alert: Watchdog - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.general }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.general | indent 8 }} -{{- end }} - description: 'This is an alert meant to ensure that the entire alerting pipeline is functional. - - This alert is always firing, therefore it should always be firing in Alertmanager - - and always fire against a receiver. There are integrations with various notification - - mechanisms that send a notification when this alert is not firing. For example the - - "DeadMansSnitch" integration in PagerDuty. - - ' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/general/watchdog - summary: An alert that should always be firing to certify that Alertmanager is working properly. - expr: vector(1) - labels: - severity: {{ dig "Watchdog" "severity" "none" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.general }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.general }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.InfoInhibitor | default false) }} - - alert: InfoInhibitor - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.general }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.general | indent 8 }} -{{- end }} - description: 'This is an alert that is used to inhibit info alerts. - - By themselves, the info-level alerts are sometimes very noisy, but they are relevant when combined with - - other alerts. - - This alert fires whenever there''s a severity="info" alert, and stops firing when another alert with a - - severity of ''warning'' or ''critical'' starts firing on the same namespace. - - This alert should be routed to a null receiver and configured to inhibit alerts with severity="info". - - ' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/general/infoinhibitor - summary: Info-level alert inhibition. - expr: ALERTS{severity = "info"} == 1 unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace) ALERTS{alertname != "InfoInhibitor", severity =~ "warning|critical", alertstate="firing"} == 1 - labels: - severity: {{ dig "InfoInhibitor" "severity" "none" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.general }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.general }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml deleted file mode 100644 index 19aa6b4e25..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- /* -Generated from 'k8s.rules.container-cpu-usage-seconds-total' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerCpuUsageSecondsTotal }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-cpu-usage-seconds-total" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: k8s.rules.container_cpu_usage_seconds_total - rules: - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, container) ( - irate(container_cpu_usage_seconds_total{job="kubelet", metrics_path="/metrics/cadvisor", image!=""}[5m]) - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) ( - 1, max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerCpuUsageSecondsTotal }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerCpuUsageSecondsTotal }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml deleted file mode 100644 index 2a08f43838..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- /* -Generated from 'k8s.rules.container-memory-cache' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerMemoryCache }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-memory-cache" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: k8s.rules.container_memory_cache - rules: - - expr: |- - container_memory_cache{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} - * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_memory_cache - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryCache }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryCache }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml deleted file mode 100644 index 85b23faafa..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- /* -Generated from 'k8s.rules.container-memory-rss' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerMemoryRss }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-memory-rss" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: k8s.rules.container_memory_rss - rules: - - expr: |- - container_memory_rss{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} - * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_memory_rss - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryRss }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryRss }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml deleted file mode 100644 index aae26802ed..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- /* -Generated from 'k8s.rules.container-memory-swap' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerMemorySwap }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-memory-swap" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: k8s.rules.container_memory_swap - rules: - - expr: |- - container_memory_swap{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} - * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_memory_swap - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemorySwap }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemorySwap }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml deleted file mode 100644 index cc7fbbd063..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- /* -Generated from 'k8s.rules.container-memory-working-set-bytes' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerMemoryWorkingSetBytes }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-memory-working-set-bytes" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: k8s.rules.container_memory_working_set_bytes - rules: - - expr: |- - container_memory_working_set_bytes{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} - * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_memory_working_set_bytes - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryWorkingSetBytes }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryWorkingSetBytes }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml deleted file mode 100644 index edba0c2e01..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml +++ /dev/null @@ -1,168 +0,0 @@ -{{- /* -Generated from 'k8s.rules.container-resource' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerResource }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-resource" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: k8s.rules.container_resource - rules: - - expr: |- - kube_pod_container_resource_requests{resource="memory",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) - group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - (kube_pod_status_phase{phase=~"Pending|Running"} == 1) - ) - record: cluster:namespace:pod_memory:active:kube_pod_container_resource_requests - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, cluster) ( - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) ( - kube_pod_container_resource_requests{resource="memory",job="{{ $kubeStateMetricsJob }}"} - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - kube_pod_status_phase{phase=~"Pending|Running"} == 1 - ) - ) - ) - record: namespace_memory:kube_pod_container_resource_requests:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - kube_pod_container_resource_requests{resource="cpu",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) - group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - (kube_pod_status_phase{phase=~"Pending|Running"} == 1) - ) - record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, cluster) ( - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) ( - kube_pod_container_resource_requests{resource="cpu",job="{{ $kubeStateMetricsJob }}"} - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - kube_pod_status_phase{phase=~"Pending|Running"} == 1 - ) - ) - ) - record: namespace_cpu:kube_pod_container_resource_requests:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - kube_pod_container_resource_limits{resource="memory",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) - group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - (kube_pod_status_phase{phase=~"Pending|Running"} == 1) - ) - record: cluster:namespace:pod_memory:active:kube_pod_container_resource_limits - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, cluster) ( - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) ( - kube_pod_container_resource_limits{resource="memory",job="{{ $kubeStateMetricsJob }}"} - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - kube_pod_status_phase{phase=~"Pending|Running"} == 1 - ) - ) - ) - record: namespace_memory:kube_pod_container_resource_limits:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - kube_pod_container_resource_limits{resource="cpu",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) - group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - (kube_pod_status_phase{phase=~"Pending|Running"} == 1) - ) - record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, cluster) ( - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) ( - kube_pod_container_resource_limits{resource="cpu",job="{{ $kubeStateMetricsJob }}"} - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - kube_pod_status_phase{phase=~"Pending|Running"} == 1 - ) - ) - ) - record: namespace_cpu:kube_pod_container_resource_limits:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml deleted file mode 100644 index 43207a748c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml +++ /dev/null @@ -1,107 +0,0 @@ -{{- /* -Generated from 'k8s.rules.pod-owner' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sPodOwner }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.pod-owner" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: k8s.rules.pod_owner - rules: - - expr: |- - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, workload, pod) ( - label_replace( - label_replace( - kube_pod_owner{job="{{ $kubeStateMetricsJob }}", owner_kind="ReplicaSet"}, - "replicaset", "$1", "owner_name", "(.*)" - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}replicaset, namespace) group_left(owner_name) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}replicaset, namespace) ( - 1, max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}replicaset, namespace, owner_name) ( - kube_replicaset_owner{job="{{ $kubeStateMetricsJob }}"} - ) - ), - "workload", "$1", "owner_name", "(.*)" - ) - ) - labels: - workload_type: deployment - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: namespace_workload_pod:kube_pod_owner:relabel - - expr: |- - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, workload, pod) ( - label_replace( - kube_pod_owner{job="{{ $kubeStateMetricsJob }}", owner_kind="DaemonSet"}, - "workload", "$1", "owner_name", "(.*)" - ) - ) - labels: - workload_type: daemonset - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: namespace_workload_pod:kube_pod_owner:relabel - - expr: |- - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, workload, pod) ( - label_replace( - kube_pod_owner{job="{{ $kubeStateMetricsJob }}", owner_kind="StatefulSet"}, - "workload", "$1", "owner_name", "(.*)" - ) - ) - labels: - workload_type: statefulset - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: namespace_workload_pod:kube_pod_owner:relabel - - expr: |- - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, workload, pod) ( - label_replace( - kube_pod_owner{job="{{ $kubeStateMetricsJob }}", owner_kind="Job"}, - "workload", "$1", "owner_name", "(.*)" - ) - ) - labels: - workload_type: job - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: namespace_workload_pod:kube_pod_owner:relabel -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.yaml deleted file mode 100644 index c61bd222ab..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.yaml +++ /dev/null @@ -1,237 +0,0 @@ -{{- /* -Generated from 'k8s.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/main/manifests/kubernetesControlPlane-prometheusRule.yaml -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8s }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: k8s.rules - rules: - - expr: |- - sum by (cluster, namespace, pod, container) ( - irate(container_cpu_usage_seconds_total{job="{{ include "exporter.kubelet.jobName" . }}", metrics_path="/metrics/cadvisor", image!=""}[5m]) - ) * on (cluster, namespace, pod) group_left(node) topk by (cluster, namespace, pod) ( - 1, max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - container_memory_working_set_bytes{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} - * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, - max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_memory_working_set_bytes - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - container_memory_rss{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} - * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, - max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_memory_rss - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - container_memory_cache{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} - * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, - max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_memory_cache - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - container_memory_swap{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} - * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, - max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) - ) - record: node_namespace_pod_container:container_memory_swap - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - kube_pod_container_resource_requests{resource="memory",job="kube-state-metrics"} * on (namespace, pod, cluster) - group_left() max by (namespace, pod, cluster) ( - (kube_pod_status_phase{phase=~"Pending|Running"} == 1) - ) - record: cluster:namespace:pod_memory:active:kube_pod_container_resource_requests - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - sum by (namespace, cluster) ( - sum by (namespace, pod, cluster) ( - max by (namespace, pod, container, cluster) ( - kube_pod_container_resource_requests{resource="memory",job="kube-state-metrics"} - ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( - kube_pod_status_phase{phase=~"Pending|Running"} == 1 - ) - ) - ) - record: namespace_memory:kube_pod_container_resource_requests:sum - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} * on (namespace, pod, cluster) - group_left() max by (namespace, pod, cluster) ( - (kube_pod_status_phase{phase=~"Pending|Running"} == 1) - ) - record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - sum by (namespace, cluster) ( - sum by (namespace, pod, cluster) ( - max by (namespace, pod, container, cluster) ( - kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} - ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( - kube_pod_status_phase{phase=~"Pending|Running"} == 1 - ) - ) - ) - record: namespace_cpu:kube_pod_container_resource_requests:sum - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - kube_pod_container_resource_limits{resource="memory",job="kube-state-metrics"} * on (namespace, pod, cluster) - group_left() max by (namespace, pod, cluster) ( - (kube_pod_status_phase{phase=~"Pending|Running"} == 1) - ) - record: cluster:namespace:pod_memory:active:kube_pod_container_resource_limits - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - sum by (namespace, cluster) ( - sum by (namespace, pod, cluster) ( - max by (namespace, pod, container, cluster) ( - kube_pod_container_resource_limits{resource="memory",job="kube-state-metrics"} - ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( - kube_pod_status_phase{phase=~"Pending|Running"} == 1 - ) - ) - ) - record: namespace_memory:kube_pod_container_resource_limits:sum - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - kube_pod_container_resource_limits{resource="cpu",job="kube-state-metrics"} * on (namespace, pod, cluster) - group_left() max by (namespace, pod, cluster) ( - (kube_pod_status_phase{phase=~"Pending|Running"} == 1) - ) - record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - sum by (namespace, cluster) ( - sum by (namespace, pod, cluster) ( - max by (namespace, pod, container, cluster) ( - kube_pod_container_resource_limits{resource="cpu",job="kube-state-metrics"} - ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( - kube_pod_status_phase{phase=~"Pending|Running"} == 1 - ) - ) - ) - record: namespace_cpu:kube_pod_container_resource_limits:sum - {{- if .Values.defaultRules.additionalRuleLabels }} - labels: - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - - expr: |- - max by (cluster, namespace, workload, pod) ( - label_replace( - label_replace( - kube_pod_owner{job="kube-state-metrics", owner_kind="ReplicaSet"}, - "replicaset", "$1", "owner_name", "(.*)" - ) * on(replicaset, namespace) group_left(owner_name) topk by(replicaset, namespace) ( - 1, max by (replicaset, namespace, owner_name) ( - kube_replicaset_owner{job="kube-state-metrics"} - ) - ), - "workload", "$1", "owner_name", "(.*)" - ) - ) - labels: - workload_type: deployment - {{- if .Values.defaultRules.additionalRuleLabels }} - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - record: namespace_workload_pod:kube_pod_owner:relabel - - expr: |- - max by (cluster, namespace, workload, pod) ( - label_replace( - kube_pod_owner{job="kube-state-metrics", owner_kind="DaemonSet"}, - "workload", "$1", "owner_name", "(.*)" - ) - ) - labels: - workload_type: daemonset - {{- if .Values.defaultRules.additionalRuleLabels }} - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - record: namespace_workload_pod:kube_pod_owner:relabel - - expr: |- - max by (cluster, namespace, workload, pod) ( - label_replace( - kube_pod_owner{job="kube-state-metrics", owner_kind="StatefulSet"}, - "workload", "$1", "owner_name", "(.*)" - ) - ) - labels: - workload_type: statefulset - {{- if .Values.defaultRules.additionalRuleLabels }} - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - record: namespace_workload_pod:kube_pod_owner:relabel - - expr: |- - max by (cluster, namespace, workload, pod) ( - label_replace( - kube_pod_owner{job="kube-state-metrics", owner_kind="Job"}, - "workload", "$1", "owner_name", "(.*)" - ) - ) - labels: - workload_type: job - {{- if .Values.defaultRules.additionalRuleLabels }} - {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} - {{- end }} - record: namespace_workload_pod:kube_pod_owner:relabel -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml deleted file mode 100644 index 02c8e7adbf..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml +++ /dev/null @@ -1,273 +0,0 @@ -{{- /* -Generated from 'kube-apiserver-availability.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeApiServer.enabled .Values.defaultRules.rules.kubeApiserverAvailability }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-apiserver-availability.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - interval: 3m - name: kube-apiserver-availability.rules - rules: - - expr: avg_over_time(code_verb:apiserver_request_total:increase1h[30d]) * 24 * 30 - record: code_verb:apiserver_request_total:increase30d - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code) (code_verb:apiserver_request_total:increase30d{verb=~"LIST|GET"}) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: code:apiserver_request_total:increase30d - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code) (code_verb:apiserver_request_total:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: code:apiserver_request_total:increase30d - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, verb, scope) (increase(apiserver_request_sli_duration_seconds_count{job="apiserver"}[1h])) - record: cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase1h - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, verb, scope) (avg_over_time(cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase1h[30d]) * 24 * 30) - record: cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, verb, scope, le) (increase(apiserver_request_sli_duration_seconds_bucket[1h])) - record: cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, verb, scope, le) (avg_over_time(cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h[30d]) * 24 * 30) - record: cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - 1 - ( - ( - # write too slow - sum by (cluster) (cluster_verb_scope:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) - - - sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"POST|PUT|PATCH|DELETE",le="1"}) - ) + - ( - # read too slow - sum by (cluster) (cluster_verb_scope:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count:increase30d{verb=~"LIST|GET"}) - - - ( - ( - sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope=~"resource|",le="1"}) - or - vector(0) - ) - + - sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="namespace",le="5"}) - + - sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="cluster",le="30"}) - ) - ) + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{code=~"5.."} or vector(0)) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d) - labels: - verb: all - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:availability30d - - expr: |- - 1 - ( - sum by (cluster) (cluster_verb_scope:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count:increase30d{verb=~"LIST|GET"}) - - - ( - # too slow - ( - sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope=~"resource|",le="1"}) - or - vector(0) - ) - + - sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="namespace",le="5"}) - + - sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="cluster",le="30"}) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{verb="read",code=~"5.."} or vector(0)) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{verb="read"}) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:availability30d - - expr: |- - 1 - ( - ( - # too slow - sum by (cluster) (cluster_verb_scope:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) - - - sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"POST|PUT|PATCH|DELETE",le="1"}) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{verb="write",code=~"5.."} or vector(0)) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{verb="write"}) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:availability30d - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,code,resource) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[5m])) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: code_resource:apiserver_request_total:rate5m - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,code,resource) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[5m])) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: code_resource:apiserver_request_total:rate5m - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"2.."}[1h])) - record: code_verb:apiserver_request_total:increase1h - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"3.."}[1h])) - record: code_verb:apiserver_request_total:increase1h - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"4.."}[1h])) - record: code_verb:apiserver_request_total:increase1h - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"5.."}[1h])) - record: code_verb:apiserver_request_total:increase1h - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml deleted file mode 100644 index 49f4400a59..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml +++ /dev/null @@ -1,440 +0,0 @@ -{{- /* -Generated from 'kube-apiserver-burnrate.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeApiServer.enabled .Values.defaultRules.rules.kubeApiserverBurnrate }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-apiserver-burnrate.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kube-apiserver-burnrate.rules - rules: - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[1d])) - - - ( - ( - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[1d])) - or - vector(0) - ) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[1d])) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[1d])) - ) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[1d])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[1d])) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate1d - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[1h])) - - - ( - ( - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[1h])) - or - vector(0) - ) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[1h])) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[1h])) - ) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[1h])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[1h])) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate1h - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[2h])) - - - ( - ( - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[2h])) - or - vector(0) - ) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[2h])) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[2h])) - ) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[2h])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[2h])) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate2h - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[30m])) - - - ( - ( - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[30m])) - or - vector(0) - ) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[30m])) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[30m])) - ) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[30m])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[30m])) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate30m - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[3d])) - - - ( - ( - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[3d])) - or - vector(0) - ) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[3d])) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[3d])) - ) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[3d])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[3d])) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate3d - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[5m])) - - - ( - ( - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[5m])) - or - vector(0) - ) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[5m])) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[5m])) - ) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[5m])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[5m])) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate5m - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[6h])) - - - ( - ( - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[6h])) - or - vector(0) - ) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[6h])) - + - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[6h])) - ) - ) - + - # errors - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[6h])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[6h])) - labels: - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate6h - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[1d])) - - - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[1d])) - ) - + - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[1d])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[1d])) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate1d - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[1h])) - - - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[1h])) - ) - + - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[1h])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[1h])) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate1h - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[2h])) - - - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[2h])) - ) - + - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[2h])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[2h])) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate2h - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[30m])) - - - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[30m])) - ) - + - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[30m])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[30m])) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate30m - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[3d])) - - - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[3d])) - ) - + - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[3d])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[3d])) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate3d - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[5m])) - - - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[5m])) - ) - + - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[5m])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[5m])) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate5m - - expr: |- - ( - ( - # too slow - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[6h])) - - - sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[6h])) - ) - + - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[6h])) - ) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[6h])) - labels: - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: apiserver_request:burnrate6h -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml deleted file mode 100644 index 5d08aa4349..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml +++ /dev/null @@ -1,53 +0,0 @@ -{{- /* -Generated from 'kube-apiserver-histogram.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeApiServer.enabled .Values.defaultRules.rules.kubeApiserverHistogram }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-apiserver-histogram.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kube-apiserver-histogram.rules - rules: - - expr: histogram_quantile(0.99, sum by (cluster, le, resource) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[5m]))) > 0 - labels: - quantile: '0.99' - verb: read - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverHistogram }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverHistogram }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.99, sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, le, resource) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[5m]))) > 0 - labels: - quantile: '0.99' - verb: write - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverHistogram }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverHistogram }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml deleted file mode 100644 index a83cf9060c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml +++ /dev/null @@ -1,159 +0,0 @@ -{{- /* -Generated from 'kube-apiserver-slos' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeApiServer.enabled .Values.defaultRules.rules.kubeApiserverSlos }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-apiserver-slos" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kube-apiserver-slos - rules: -{{- if not (.Values.defaultRules.disabled.KubeAPIErrorBudgetBurn | default false) }} - - alert: KubeAPIErrorBudgetBurn - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos | indent 8 }} -{{- end }} - description: The API server is burning too much error budget. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapierrorbudgetburn - summary: The API server is burning too much error budget. - expr: |- - sum(apiserver_request:burnrate1h) > (14.40 * 0.01000) - and - sum(apiserver_request:burnrate5m) > (14.40 * 0.01000) - for: {{ dig "KubeAPIErrorBudgetBurn" "for" "2m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - long: 1h - severity: {{ dig "KubeAPIErrorBudgetBurn" "severity" "critical" .Values.customRules }} - short: 5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeAPIErrorBudgetBurn | default false) }} - - alert: KubeAPIErrorBudgetBurn - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos | indent 8 }} -{{- end }} - description: The API server is burning too much error budget. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapierrorbudgetburn - summary: The API server is burning too much error budget. - expr: |- - sum(apiserver_request:burnrate6h) > (6.00 * 0.01000) - and - sum(apiserver_request:burnrate30m) > (6.00 * 0.01000) - for: {{ dig "KubeAPIErrorBudgetBurn" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - long: 6h - severity: {{ dig "KubeAPIErrorBudgetBurn" "severity" "critical" .Values.customRules }} - short: 30m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeAPIErrorBudgetBurn | default false) }} - - alert: KubeAPIErrorBudgetBurn - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos | indent 8 }} -{{- end }} - description: The API server is burning too much error budget. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapierrorbudgetburn - summary: The API server is burning too much error budget. - expr: |- - sum(apiserver_request:burnrate1d) > (3.00 * 0.01000) - and - sum(apiserver_request:burnrate2h) > (3.00 * 0.01000) - for: {{ dig "KubeAPIErrorBudgetBurn" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - long: 1d - severity: {{ dig "KubeAPIErrorBudgetBurn" "severity" "warning" .Values.customRules }} - short: 2h - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeAPIErrorBudgetBurn | default false) }} - - alert: KubeAPIErrorBudgetBurn - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos | indent 8 }} -{{- end }} - description: The API server is burning too much error budget. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapierrorbudgetburn - summary: The API server is burning too much error budget. - expr: |- - sum(apiserver_request:burnrate3d) > (1.00 * 0.01000) - and - sum(apiserver_request:burnrate6h) > (1.00 * 0.01000) - for: {{ dig "KubeAPIErrorBudgetBurn" "for" "3h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - long: 3d - severity: {{ dig "KubeAPIErrorBudgetBurn" "severity" "warning" .Values.customRules }} - short: 6h - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml deleted file mode 100644 index fc199f11f8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml +++ /dev/null @@ -1,49 +0,0 @@ -{{- /* -Generated from 'kube-prometheus-general.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubePrometheusGeneral }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-prometheus-general.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kube-prometheus-general.rules - rules: - - expr: count without(instance, pod, node) (up == 1) - record: count:up1 - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusGeneral }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusGeneral }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: count without(instance, pod, node) (up == 0) - record: count:up0 - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusGeneral }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusGeneral }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml deleted file mode 100644 index 63f721f42a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml +++ /dev/null @@ -1,93 +0,0 @@ -{{- /* -Generated from 'kube-prometheus-node-recording.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubePrometheusNodeRecording }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-prometheus-node-recording.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kube-prometheus-node-recording.rules - rules: - - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[3m])) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) - record: instance:node_cpu:rate:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum(rate(node_network_receive_bytes_total[3m])) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) - record: instance:node_network_receive_bytes:rate:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum(rate(node_network_transmit_bytes_total[3m])) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) - record: instance:node_network_transmit_bytes:rate:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[5m])) WITHOUT (cpu, mode) / ON ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) GROUP_LEFT() count(sum(node_cpu_seconds_total) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance, cpu)) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) - record: instance:node_cpu:ratio - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[5m])) - record: cluster:node_cpu:sum_rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: cluster:node_cpu:sum_rate5m / count(sum(node_cpu_seconds_total) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance, cpu)) - record: cluster:node_cpu:ratio - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml deleted file mode 100644 index 9f8bf60228..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml +++ /dev/null @@ -1,135 +0,0 @@ -{{- /* -Generated from 'kube-scheduler.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeScheduler.enabled .Values.defaultRules.rules.kubeSchedulerRecording }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-scheduler.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kube-scheduler.rules - rules: - - expr: histogram_quantile(0.99, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="{{ include "exporter.kubeScheduler.jobName" . }}"}[5m])) without(instance, pod)) - labels: - quantile: '0.99' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.99, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="{{ include "exporter.kubeScheduler.jobName" . }}"}[5m])) without(instance, pod)) - labels: - quantile: '0.99' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.99, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) - labels: - quantile: '0.99' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.9, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) - labels: - quantile: '0.9' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.9, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) - labels: - quantile: '0.9' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.9, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) - labels: - quantile: '0.9' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.5, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) - labels: - quantile: '0.5' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.5, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) - labels: - quantile: '0.5' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.5, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) - labels: - quantile: '0.5' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-state-metrics.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-state-metrics.yaml deleted file mode 100644 index 7f3600fb71..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kube-state-metrics.yaml +++ /dev/null @@ -1,152 +0,0 @@ -{{- /* -Generated from 'kube-state-metrics' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubeStateMetrics }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-state-metrics" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kube-state-metrics - rules: -{{- if not (.Values.defaultRules.disabled.KubeStateMetricsListErrors | default false) }} - - alert: KubeStateMetricsListErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics | indent 8 }} -{{- end }} - description: kube-state-metrics is experiencing errors at an elevated rate in list operations. This is likely causing it to not be able to expose metrics about Kubernetes objects correctly or at all. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kube-state-metrics/kubestatemetricslisterrors - summary: kube-state-metrics is experiencing errors in list operations. - expr: |- - (sum(rate(kube_state_metrics_list_total{job="{{ $kubeStateMetricsJob }}",result="error"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - / - sum(rate(kube_state_metrics_list_total{job="{{ $kubeStateMetricsJob }}"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) - > 0.01 - for: {{ dig "KubeStateMetricsListErrors" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeStateMetricsListErrors" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeStateMetricsWatchErrors | default false) }} - - alert: KubeStateMetricsWatchErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics | indent 8 }} -{{- end }} - description: kube-state-metrics is experiencing errors at an elevated rate in watch operations. This is likely causing it to not be able to expose metrics about Kubernetes objects correctly or at all. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kube-state-metrics/kubestatemetricswatcherrors - summary: kube-state-metrics is experiencing errors in watch operations. - expr: |- - (sum(rate(kube_state_metrics_watch_total{job="{{ $kubeStateMetricsJob }}",result="error"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - / - sum(rate(kube_state_metrics_watch_total{job="{{ $kubeStateMetricsJob }}"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) - > 0.01 - for: {{ dig "KubeStateMetricsWatchErrors" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeStateMetricsWatchErrors" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeStateMetricsShardingMismatch | default false) }} - - alert: KubeStateMetricsShardingMismatch - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics | indent 8 }} -{{- end }} - description: kube-state-metrics pods are running with different --total-shards configuration, some Kubernetes objects may be exposed multiple times or not exposed at all. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kube-state-metrics/kubestatemetricsshardingmismatch - summary: kube-state-metrics sharding is misconfigured. - expr: stdvar (kube_state_metrics_total_shards{job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) != 0 - for: {{ dig "KubeStateMetricsShardingMismatch" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeStateMetricsShardingMismatch" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeStateMetricsShardsMissing | default false) }} - - alert: KubeStateMetricsShardsMissing - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics | indent 8 }} -{{- end }} - description: kube-state-metrics shards are missing, some Kubernetes objects are not being exposed. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kube-state-metrics/kubestatemetricsshardsmissing - summary: kube-state-metrics shards are missing. - expr: |- - 2^max(kube_state_metrics_total_shards{job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - 1 - - - sum( 2 ^ max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, shard_ordinal) (kube_state_metrics_shard_ordinal{job="{{ $kubeStateMetricsJob }}"}) ) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - != 0 - for: {{ dig "KubeStateMetricsShardsMissing" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeStateMetricsShardsMissing" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubelet.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubelet.rules.yaml deleted file mode 100644 index 8cd03baa43..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubelet.rules.yaml +++ /dev/null @@ -1,65 +0,0 @@ -{{- /* -Generated from 'kubelet.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubelet }} -{{- if (include "exporter.kubelet.enabled" .)}} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubelet.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubelet.rules - rules: - - expr: histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, le) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) group_left(node) kubelet_node_name{job="kubelet", metrics_path="/metrics"}) - labels: - quantile: '0.99' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubelet }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubelet }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.9, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, le) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) group_left(node) kubelet_node_name{job="kubelet", metrics_path="/metrics"}) - labels: - quantile: '0.9' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubelet }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubelet }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile - - expr: histogram_quantile(0.5, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, le) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) group_left(node) kubelet_node_name{job="kubelet", metrics_path="/metrics"}) - labels: - quantile: '0.5' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubelet }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubelet }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-apps.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-apps.yaml deleted file mode 100644 index 76215b3999..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-apps.yaml +++ /dev/null @@ -1,568 +0,0 @@ -{{- /* -Generated from 'kubernetes-apps' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesApps }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -{{- $targetNamespace := .Values.defaultRules.appNamespacesTarget }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-apps" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-apps - rules: -{{- if not (.Values.defaultRules.disabled.KubePodCrashLooping | default false) }} - - alert: KubePodCrashLooping - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: 'Pod {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod {{`}}`}} ({{`{{`}} $labels.container {{`}}`}}) is in waiting state (reason: "CrashLoopBackOff").' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepodcrashlooping - summary: Pod is crash looping. - expr: max_over_time(kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff", job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[5m]) >= 1 - for: {{ dig "KubePodCrashLooping" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubePodCrashLooping" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubePodNotReady | default false) }} - - alert: KubePodNotReady - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: Pod {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod {{`}}`}} has been in a non-ready state for longer than 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepodnotready - summary: Pod has been in a non-ready state for more than 15 minutes. - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - kube_pod_status_phase{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}", phase=~"Pending|Unknown|Failed"} - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left(owner_kind) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( - 1, max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, owner_kind, cluster) (kube_pod_owner{owner_kind!="Job"}) - ) - ) > 0 - for: {{ dig "KubePodNotReady" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubePodNotReady" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeDeploymentGenerationMismatch | default false) }} - - alert: KubeDeploymentGenerationMismatch - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: Deployment generation for {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.deployment {{`}}`}} does not match, this indicates that the Deployment has failed but has not been rolled back. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedeploymentgenerationmismatch - summary: Deployment generation mismatch due to possible roll-back - expr: |- - kube_deployment_status_observed_generation{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - kube_deployment_metadata_generation{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - for: {{ dig "KubeDeploymentGenerationMismatch" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeDeploymentGenerationMismatch" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeDeploymentReplicasMismatch | default false) }} - - alert: KubeDeploymentReplicasMismatch - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: Deployment {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.deployment {{`}}`}} has not matched the expected number of replicas for longer than 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedeploymentreplicasmismatch - summary: Deployment has not matched the expected number of replicas. - expr: |- - ( - kube_deployment_spec_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - > - kube_deployment_status_replicas_available{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - ) and ( - changes(kube_deployment_status_replicas_updated{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[10m]) - == - 0 - ) - for: {{ dig "KubeDeploymentReplicasMismatch" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeDeploymentReplicasMismatch" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeDeploymentRolloutStuck | default false) }} - - alert: KubeDeploymentRolloutStuck - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: Rollout of deployment {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.deployment {{`}}`}} is not progressing for longer than 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedeploymentrolloutstuck - summary: Deployment rollout is not progressing. - expr: |- - kube_deployment_status_condition{condition="Progressing", status="false",job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != 0 - for: {{ dig "KubeDeploymentRolloutStuck" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeDeploymentRolloutStuck" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeStatefulSetReplicasMismatch | default false) }} - - alert: KubeStatefulSetReplicasMismatch - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: StatefulSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.statefulset {{`}}`}} has not matched the expected number of replicas for longer than 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubestatefulsetreplicasmismatch - summary: StatefulSet has not matched the expected number of replicas. - expr: |- - ( - kube_statefulset_status_replicas_ready{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - kube_statefulset_status_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - ) and ( - changes(kube_statefulset_status_replicas_updated{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[10m]) - == - 0 - ) - for: {{ dig "KubeStatefulSetReplicasMismatch" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeStatefulSetReplicasMismatch" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeStatefulSetGenerationMismatch | default false) }} - - alert: KubeStatefulSetGenerationMismatch - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: StatefulSet generation for {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.statefulset {{`}}`}} does not match, this indicates that the StatefulSet has failed but has not been rolled back. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubestatefulsetgenerationmismatch - summary: StatefulSet generation mismatch due to possible roll-back - expr: |- - kube_statefulset_status_observed_generation{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - kube_statefulset_metadata_generation{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - for: {{ dig "KubeStatefulSetGenerationMismatch" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeStatefulSetGenerationMismatch" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeStatefulSetUpdateNotRolledOut | default false) }} - - alert: KubeStatefulSetUpdateNotRolledOut - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: StatefulSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.statefulset {{`}}`}} update has not been rolled out. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubestatefulsetupdatenotrolledout - summary: StatefulSet update has not been rolled out. - expr: |- - ( - max without (revision) ( - kube_statefulset_status_current_revision{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - unless - kube_statefulset_status_update_revision{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - ) - * - ( - kube_statefulset_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - kube_statefulset_status_replicas_updated{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - ) - ) and ( - changes(kube_statefulset_status_replicas_updated{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[5m]) - == - 0 - ) - for: {{ dig "KubeStatefulSetUpdateNotRolledOut" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeStatefulSetUpdateNotRolledOut" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeDaemonSetRolloutStuck | default false) }} - - alert: KubeDaemonSetRolloutStuck - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: DaemonSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.daemonset {{`}}`}} has not finished or progressed for at least 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedaemonsetrolloutstuck - summary: DaemonSet rollout is stuck. - expr: |- - ( - ( - kube_daemonset_status_current_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - kube_daemonset_status_desired_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - ) or ( - kube_daemonset_status_number_misscheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - 0 - ) or ( - kube_daemonset_status_updated_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - kube_daemonset_status_desired_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - ) or ( - kube_daemonset_status_number_available{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - kube_daemonset_status_desired_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - ) - ) and ( - changes(kube_daemonset_status_updated_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[5m]) - == - 0 - ) - for: {{ dig "KubeDaemonSetRolloutStuck" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeDaemonSetRolloutStuck" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeContainerWaiting | default false) }} - - alert: KubeContainerWaiting - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: pod/{{`{{`}} $labels.pod {{`}}`}} in namespace {{`{{`}} $labels.namespace {{`}}`}} on container {{`{{`}} $labels.container{{`}}`}} has been in waiting state for longer than 1 hour. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubecontainerwaiting - summary: Pod container waiting longer than 1 hour - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) (kube_pod_container_status_waiting_reason{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}) > 0 - for: {{ dig "KubeContainerWaiting" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeContainerWaiting" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeDaemonSetNotScheduled | default false) }} - - alert: KubeDaemonSetNotScheduled - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: '{{`{{`}} $value {{`}}`}} Pods of DaemonSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.daemonset {{`}}`}} are not scheduled.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedaemonsetnotscheduled - summary: DaemonSet pods are not scheduled. - expr: |- - kube_daemonset_status_desired_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - - - kube_daemonset_status_current_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} > 0 - for: {{ dig "KubeDaemonSetNotScheduled" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeDaemonSetNotScheduled" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeDaemonSetMisScheduled | default false) }} - - alert: KubeDaemonSetMisScheduled - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: '{{`{{`}} $value {{`}}`}} Pods of DaemonSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.daemonset {{`}}`}} are running where they are not supposed to run.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedaemonsetmisscheduled - summary: DaemonSet pods are misscheduled. - expr: kube_daemonset_status_number_misscheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} > 0 - for: {{ dig "KubeDaemonSetMisScheduled" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeDaemonSetMisScheduled" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeJobNotCompleted | default false) }} - - alert: KubeJobNotCompleted - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: Job {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.job_name {{`}}`}} is taking more than {{`{{`}} "43200" | humanizeDuration {{`}}`}} to complete. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubejobnotcompleted - summary: Job did not complete in time - expr: |- - time() - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, job_name, cluster) (kube_job_status_start_time{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - and - kube_job_status_active{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} > 0) > 43200 - labels: - severity: {{ dig "KubeJobNotCompleted" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeJobFailed | default false) }} - - alert: KubeJobFailed - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: Job {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.job_name {{`}}`}} failed to complete. Removing failed job after investigation should clear this alert. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubejobfailed - summary: Job failed to complete. - expr: kube_job_failed{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} > 0 - for: {{ dig "KubeJobFailed" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeJobFailed" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeHpaReplicasMismatch | default false) }} - - alert: KubeHpaReplicasMismatch - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: HPA {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.horizontalpodautoscaler {{`}}`}} has not matched the desired number of replicas for longer than 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubehpareplicasmismatch - summary: HPA has not matched desired number of replicas. - expr: |- - (kube_horizontalpodautoscaler_status_desired_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - != - kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}) - and - (kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - > - kube_horizontalpodautoscaler_spec_min_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}) - and - (kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - < - kube_horizontalpodautoscaler_spec_max_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}) - and - changes(kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[15m]) == 0 - for: {{ dig "KubeHpaReplicasMismatch" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeHpaReplicasMismatch" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeHpaMaxedOut | default false) }} - - alert: KubeHpaMaxedOut - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} -{{- end }} - description: HPA {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.horizontalpodautoscaler {{`}}`}} has been running at max replicas for longer than 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubehpamaxedout - summary: HPA is running at max replicas - expr: |- - kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - == - kube_horizontalpodautoscaler_spec_max_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} - for: {{ dig "KubeHpaMaxedOut" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeHpaMaxedOut" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-resources.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-resources.yaml deleted file mode 100644 index 9111285250..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-resources.yaml +++ /dev/null @@ -1,282 +0,0 @@ -{{- /* -Generated from 'kubernetes-resources' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesResources }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-resources" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-resources - rules: -{{- if not (.Values.defaultRules.disabled.KubeCPUOvercommit | default false) }} - - alert: KubeCPUOvercommit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} -{{- end }} - description: Cluster {{`{{`}} $labels.cluster {{`}}`}} has overcommitted CPU resource requests for Pods by {{`{{`}} $value {{`}}`}} CPU shares and cannot tolerate node failure. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubecpuovercommit - summary: Cluster has overcommitted CPU resource requests. - expr: |- - sum(namespace_cpu:kube_pod_container_resource_requests:sum{job="{{ $kubeStateMetricsJob }}",}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - (sum(kube_node_status_allocatable{job="{{ $kubeStateMetricsJob }}",resource="cpu"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - max(kube_node_status_allocatable{job="{{ $kubeStateMetricsJob }}",resource="cpu"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) > 0 - and - (sum(kube_node_status_allocatable{job="{{ $kubeStateMetricsJob }}",resource="cpu"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - max(kube_node_status_allocatable{job="{{ $kubeStateMetricsJob }}",resource="cpu"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) > 0 - for: {{ dig "KubeCPUOvercommit" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeCPUOvercommit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeMemoryOvercommit | default false) }} - - alert: KubeMemoryOvercommit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} -{{- end }} - description: Cluster {{`{{`}} $labels.cluster {{`}}`}} has overcommitted memory resource requests for Pods by {{`{{`}} $value | humanize {{`}}`}} bytes and cannot tolerate node failure. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubememoryovercommit - summary: Cluster has overcommitted memory resource requests. - expr: |- - sum(namespace_memory:kube_pod_container_resource_requests:sum{}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - (sum(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - max(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) > 0 - and - (sum(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - max(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) > 0 - for: {{ dig "KubeMemoryOvercommit" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeMemoryOvercommit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeCPUQuotaOvercommit | default false) }} - - alert: KubeCPUQuotaOvercommit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} -{{- end }} - description: Cluster {{`{{`}} $labels.cluster {{`}}`}} has overcommitted CPU resource requests for Namespaces. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubecpuquotaovercommit - summary: Cluster has overcommitted CPU resource requests. - expr: |- - sum(min without(resource) (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard", resource=~"(cpu|requests.cpu)"})) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - / - sum(kube_node_status_allocatable{resource="cpu", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - > 1.5 - for: {{ dig "KubeCPUQuotaOvercommit" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeCPUQuotaOvercommit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeMemoryQuotaOvercommit | default false) }} - - alert: KubeMemoryQuotaOvercommit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} -{{- end }} - description: Cluster {{`{{`}} $labels.cluster {{`}}`}} has overcommitted memory resource requests for Namespaces. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubememoryquotaovercommit - summary: Cluster has overcommitted memory resource requests. - expr: |- - sum(min without(resource) (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard", resource=~"(memory|requests.memory)"})) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - / - sum(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - > 1.5 - for: {{ dig "KubeMemoryQuotaOvercommit" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeMemoryQuotaOvercommit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeQuotaAlmostFull | default false) }} - - alert: KubeQuotaAlmostFull - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} -{{- end }} - description: Namespace {{`{{`}} $labels.namespace {{`}}`}} is using {{`{{`}} $value | humanizePercentage {{`}}`}} of its {{`{{`}} $labels.resource {{`}}`}} quota. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubequotaalmostfull - summary: Namespace quota is going to be full. - expr: |- - kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="used"} - / ignoring(instance, job, type) - (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard"} > 0) - > 0.9 < 1 - for: {{ dig "KubeQuotaAlmostFull" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeQuotaAlmostFull" "severity" "info" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeQuotaFullyUsed | default false) }} - - alert: KubeQuotaFullyUsed - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} -{{- end }} - description: Namespace {{`{{`}} $labels.namespace {{`}}`}} is using {{`{{`}} $value | humanizePercentage {{`}}`}} of its {{`{{`}} $labels.resource {{`}}`}} quota. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubequotafullyused - summary: Namespace quota is fully used. - expr: |- - kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="used"} - / ignoring(instance, job, type) - (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard"} > 0) - == 1 - for: {{ dig "KubeQuotaFullyUsed" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeQuotaFullyUsed" "severity" "info" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeQuotaExceeded | default false) }} - - alert: KubeQuotaExceeded - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} -{{- end }} - description: Namespace {{`{{`}} $labels.namespace {{`}}`}} is using {{`{{`}} $value | humanizePercentage {{`}}`}} of its {{`{{`}} $labels.resource {{`}}`}} quota. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubequotaexceeded - summary: Namespace quota has exceeded the limits. - expr: |- - kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="used"} - / ignoring(instance, job, type) - (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard"} > 0) - > 1 - for: {{ dig "KubeQuotaExceeded" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeQuotaExceeded" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.CPUThrottlingHigh | default false) }} - - alert: CPUThrottlingHigh - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} -{{- end }} - description: '{{`{{`}} $value | humanizePercentage {{`}}`}} throttling of CPU in namespace {{`{{`}} $labels.namespace {{`}}`}} for container {{`{{`}} $labels.container {{`}}`}} in pod {{`{{`}} $labels.pod {{`}}`}}.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/cputhrottlinghigh - summary: Processes experience elevated CPU throttling. - expr: |- - sum(increase(container_cpu_cfs_throttled_periods_total{container!="", }[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, container, pod, namespace) - / - sum(increase(container_cpu_cfs_periods_total{}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, container, pod, namespace) - > ( 25 / 100 ) - for: {{ dig "CPUThrottlingHigh" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "CPUThrottlingHigh" "severity" "info" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-storage.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-storage.yaml deleted file mode 100644 index 809e544885..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-storage.yaml +++ /dev/null @@ -1,216 +0,0 @@ -{{- /* -Generated from 'kubernetes-storage' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesStorage }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -{{- $targetNamespace := .Values.defaultRules.appNamespacesTarget }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-storage" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-storage - rules: -{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeFillingUp | default false) }} - - alert: KubePersistentVolumeFillingUp - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} -{{- end }} - description: The PersistentVolume claimed by {{`{{`}} $labels.persistentvolumeclaim {{`}}`}} in Namespace {{`{{`}} $labels.namespace {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} is only {{`{{`}} $value | humanizePercentage {{`}}`}} free. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumefillingup - summary: PersistentVolume is filling up. - expr: |- - kubelet_volume_stats_available_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} - / - kubelet_volume_stats_capacity_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} - < 0.03 - and - kubelet_volume_stats_used_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} > 0 - unless on(namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 - unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 - for: {{ dig "KubePersistentVolumeFillingUp" "for" "1m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubePersistentVolumeFillingUp" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeFillingUp | default false) }} - - alert: KubePersistentVolumeFillingUp - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} -{{- end }} - description: Based on recent sampling, the PersistentVolume claimed by {{`{{`}} $labels.persistentvolumeclaim {{`}}`}} in Namespace {{`{{`}} $labels.namespace {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} is expected to fill up within four days. Currently {{`{{`}} $value | humanizePercentage {{`}}`}} is available. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumefillingup - summary: PersistentVolume is filling up. - expr: |- - ( - kubelet_volume_stats_available_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} - / - kubelet_volume_stats_capacity_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} - ) < 0.15 - and - kubelet_volume_stats_used_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} > 0 - and - predict_linear(kubelet_volume_stats_available_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"}[6h], 4 * 24 * 3600) < 0 - unless on(namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 - unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 - for: {{ dig "KubePersistentVolumeFillingUp" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubePersistentVolumeFillingUp" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeInodesFillingUp | default false) }} - - alert: KubePersistentVolumeInodesFillingUp - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} -{{- end }} - description: The PersistentVolume claimed by {{`{{`}} $labels.persistentvolumeclaim {{`}}`}} in Namespace {{`{{`}} $labels.namespace {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} only has {{`{{`}} $value | humanizePercentage {{`}}`}} free inodes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumeinodesfillingup - summary: PersistentVolumeInodes are filling up. - expr: |- - ( - kubelet_volume_stats_inodes_free{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} - / - kubelet_volume_stats_inodes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} - ) < 0.03 - and - kubelet_volume_stats_inodes_used{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} > 0 - unless on(namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 - unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 - for: {{ dig "KubePersistentVolumeInodesFillingUp" "for" "1m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubePersistentVolumeInodesFillingUp" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeInodesFillingUp | default false) }} - - alert: KubePersistentVolumeInodesFillingUp - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} -{{- end }} - description: Based on recent sampling, the PersistentVolume claimed by {{`{{`}} $labels.persistentvolumeclaim {{`}}`}} in Namespace {{`{{`}} $labels.namespace {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} is expected to run out of inodes within four days. Currently {{`{{`}} $value | humanizePercentage {{`}}`}} of its inodes are free. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumeinodesfillingup - summary: PersistentVolumeInodes are filling up. - expr: |- - ( - kubelet_volume_stats_inodes_free{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} - / - kubelet_volume_stats_inodes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} - ) < 0.15 - and - kubelet_volume_stats_inodes_used{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} > 0 - and - predict_linear(kubelet_volume_stats_inodes_free{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"}[6h], 4 * 24 * 3600) < 0 - unless on(namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 - unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 - for: {{ dig "KubePersistentVolumeInodesFillingUp" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubePersistentVolumeInodesFillingUp" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeErrors | default false) }} - - alert: KubePersistentVolumeErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} -{{- end }} - description: The persistent volume {{`{{`}} $labels.persistentvolume {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} has status {{`{{`}} $labels.phase {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumeerrors - summary: PersistentVolume is having issues with provisioning. - expr: kube_persistentvolume_status_phase{phase=~"Failed|Pending",job="{{ $kubeStateMetricsJob }}"} > 0 - for: {{ dig "KubePersistentVolumeErrors" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubePersistentVolumeErrors" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml deleted file mode 100644 index 6dd61b5f5c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml +++ /dev/null @@ -1,193 +0,0 @@ -{{- /* -Generated from 'kubernetes-system-apiserver' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesSystem }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-apiserver" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-system-apiserver - rules: -{{- if not (.Values.defaultRules.disabled.KubeClientCertificateExpiration | default false) }} - - alert: KubeClientCertificateExpiration - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: A client certificate used to authenticate to kubernetes apiserver is expiring in less than 7.0 days. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeclientcertificateexpiration - summary: Client certificate is about to expire. - expr: apiserver_client_certificate_expiration_seconds_count{job="apiserver"} > 0 and on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}job) histogram_quantile(0.01, sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}job, le) (rate(apiserver_client_certificate_expiration_seconds_bucket{job="apiserver"}[5m]))) < 604800 - for: {{ dig "KubeClientCertificateExpiration" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeClientCertificateExpiration" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeClientCertificateExpiration | default false) }} - - alert: KubeClientCertificateExpiration - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: A client certificate used to authenticate to kubernetes apiserver is expiring in less than 24.0 hours. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeclientcertificateexpiration - summary: Client certificate is about to expire. - expr: apiserver_client_certificate_expiration_seconds_count{job="apiserver"} > 0 and on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}job) histogram_quantile(0.01, sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}job, le) (rate(apiserver_client_certificate_expiration_seconds_bucket{job="apiserver"}[5m]))) < 86400 - for: {{ dig "KubeClientCertificateExpiration" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeClientCertificateExpiration" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeAggregatedAPIErrors | default false) }} - - alert: KubeAggregatedAPIErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Kubernetes aggregated API {{`{{`}} $labels.name {{`}}`}}/{{`{{`}} $labels.namespace {{`}}`}} has reported errors. It has appeared unavailable {{`{{`}} $value | humanize {{`}}`}} times averaged over the past 10m. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeaggregatedapierrors - summary: Kubernetes aggregated API has reported errors. - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}name, namespace, cluster)(increase(aggregator_unavailable_apiservice_total{job="apiserver"}[10m])) > 4 - labels: - severity: {{ dig "KubeAggregatedAPIErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeAggregatedAPIDown | default false) }} - - alert: KubeAggregatedAPIDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Kubernetes aggregated API {{`{{`}} $labels.name {{`}}`}}/{{`{{`}} $labels.namespace {{`}}`}} has been only {{`{{`}} $value | humanize {{`}}`}}% available over the last 10m. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeaggregatedapidown - summary: Kubernetes aggregated API is down. - expr: (1 - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}name, namespace, cluster)(avg_over_time(aggregator_unavailable_apiservice{job="apiserver"}[10m]))) * 100 < 85 - for: {{ dig "KubeAggregatedAPIDown" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeAggregatedAPIDown" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if .Values.kubeApiServer.enabled }} -{{- if not (.Values.defaultRules.disabled.KubeAPIDown | default false) }} - - alert: KubeAPIDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: KubeAPI has disappeared from Prometheus target discovery. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapidown - summary: Target disappeared from Prometheus target discovery. - expr: absent(up{job="apiserver"} == 1) - for: {{ dig "KubeAPIDown" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeAPIDown" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeAPITerminatedRequests | default false) }} - - alert: KubeAPITerminatedRequests - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: The kubernetes apiserver has terminated {{`{{`}} $value | humanizePercentage {{`}}`}} of its incoming requests. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapiterminatedrequests - summary: The kubernetes apiserver has terminated {{`{{`}} $value | humanizePercentage {{`}}`}} of its incoming requests. - expr: sum(rate(apiserver_request_terminations_total{job="apiserver"}[10m])) / ( sum(rate(apiserver_request_total{job="apiserver"}[10m])) + sum(rate(apiserver_request_terminations_total{job="apiserver"}[10m])) ) > 0.20 - for: {{ dig "KubeAPITerminatedRequests" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeAPITerminatedRequests" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml deleted file mode 100644 index 43b324596e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- /* -Generated from 'kubernetes-system-controller-manager' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubeControllerManager }} -{{- if (include "exporter.kubeControllerManager.enabled" .)}} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-controller-manager" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-system-controller-manager - rules: -{{- if .Values.kubeControllerManager.enabled }} -{{- if not (.Values.defaultRules.disabled.KubeControllerManagerDown | default false) }} - - alert: KubeControllerManagerDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeControllerManager }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeControllerManager | indent 8 }} -{{- end }} - description: KubeControllerManager has disappeared from Prometheus target discovery. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubecontrollermanagerdown - summary: Target disappeared from Prometheus target discovery. - expr: absent(up{job="{{ include "exporter.kubeControllerManager.jobName" . }}"} == 1) - for: 15m - labels: - severity: {{ dig "KubeControllerManagerDown" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeControllerManager }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeControllerManager }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} - diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml deleted file mode 100644 index 2000acece2..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml +++ /dev/null @@ -1,52 +0,0 @@ -{{- /* -Generated from 'kubernetes-system-kube-proxy' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeProxy.enabled .Values.defaultRules.rules.kubeProxy }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-kube-proxy" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-system-kube-proxy - rules: -{{- if not (.Values.defaultRules.disabled.KubeProxyDown | default false) }} - - alert: KubeProxyDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeProxy }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeProxy | indent 8 }} -{{- end }} - description: KubeProxy has disappeared from Prometheus target discovery. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeproxydown - summary: Target disappeared from Prometheus target discovery. - expr: absent(up{job="{{ include "exporter.kubeProxy.jobName" . }}"} == 1) - for: 15m - labels: - severity: {{ dig "KubeProxyDown" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeProxy }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeProxy }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml deleted file mode 100644 index d2cf87422d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml +++ /dev/null @@ -1,379 +0,0 @@ -{{- /* -Generated from 'kubernetes-system-kubelet' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesSystem }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-kubelet" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-system-kubelet - rules: -{{- if not (.Values.defaultRules.disabled.KubeNodeNotReady | default false) }} - - alert: KubeNodeNotReady - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: '{{`{{`}} $labels.node {{`}}`}} has been unready for more than 15 minutes.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubenodenotready - summary: Node is not ready. - expr: kube_node_status_condition{job="{{ $kubeStateMetricsJob }}",condition="Ready",status="true"} == 0 - for: {{ dig "KubeNodeNotReady" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeNodeNotReady" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeNodeUnreachable | default false) }} - - alert: KubeNodeUnreachable - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: '{{`{{`}} $labels.node {{`}}`}} is unreachable and some workloads may be rescheduled.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubenodeunreachable - summary: Node is unreachable. - expr: (kube_node_spec_taint{job="{{ $kubeStateMetricsJob }}",key="node.kubernetes.io/unreachable",effect="NoSchedule"} unless ignoring(key,value) kube_node_spec_taint{job="{{ $kubeStateMetricsJob }}",key=~"ToBeDeletedByClusterAutoscaler|cloud.google.com/impending-node-termination|aws-node-termination-handler/spot-itn"}) == 1 - for: {{ dig "KubeNodeUnreachable" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeNodeUnreachable" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletTooManyPods | default false) }} - - alert: KubeletTooManyPods - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Kubelet '{{`{{`}} $labels.node {{`}}`}}' is running at {{`{{`}} $value | humanizePercentage {{`}}`}} of its Pod capacity. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubelettoomanypods - summary: Kubelet is running at capacity. - expr: |- - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) ( - (kube_pod_status_phase{job="{{ $kubeStateMetricsJob }}",phase="Running"} == 1) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance,pod,namespace,cluster) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance,pod,namespace,cluster) (1, kube_pod_info{job="{{ $kubeStateMetricsJob }}"}) - ) - / - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) ( - kube_node_status_capacity{job="{{ $kubeStateMetricsJob }}",resource="pods"} != 1 - ) > 0.95 - for: {{ dig "KubeletTooManyPods" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeletTooManyPods" "severity" "info" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeNodeReadinessFlapping | default false) }} - - alert: KubeNodeReadinessFlapping - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: The readiness status of node {{`{{`}} $labels.node {{`}}`}} has changed {{`{{`}} $value {{`}}`}} times in the last 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubenodereadinessflapping - summary: Node readiness status is flapping. - expr: sum(changes(kube_node_status_condition{job="{{ $kubeStateMetricsJob }}",status="true",condition="Ready"}[15m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) > 2 - for: {{ dig "KubeNodeReadinessFlapping" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeNodeReadinessFlapping" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletPlegDurationHigh | default false) }} - - alert: KubeletPlegDurationHigh - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: The Kubelet Pod Lifecycle Event Generator has a 99th percentile duration of {{`{{`}} $value {{`}}`}} seconds on node {{`{{`}} $labels.node {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletplegdurationhigh - summary: Kubelet Pod Lifecycle Event Generator is taking too long to relist. - expr: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile{quantile="0.99"} >= 10 - for: {{ dig "KubeletPlegDurationHigh" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeletPlegDurationHigh" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletPodStartUpLatencyHigh | default false) }} - - alert: KubeletPodStartUpLatencyHigh - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Kubelet Pod startup 99th percentile latency is {{`{{`}} $value {{`}}`}} seconds on node {{`{{`}} $labels.node {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletpodstartuplatencyhigh - summary: Kubelet Pod startup latency is too high. - expr: histogram_quantile(0.99, sum(rate(kubelet_pod_worker_duration_seconds_bucket{job="{{ include "exporter.kubelet.jobName" . }}", metrics_path="/metrics"}[5m])) by (cluster, instance, le)) * on(cluster, instance) group_left(node) kubelet_node_name{job="{{ include "exporter.kubelet.jobName" . }}", metrics_path="/metrics"} > 60 - for: 15m - labels: - severity: {{ dig "KubeletPodStartUpLatencyHigh" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletClientCertificateExpiration | default false) }} - - alert: KubeletClientCertificateExpiration - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Client certificate for Kubelet on node {{`{{`}} $labels.node {{`}}`}} expires in {{`{{`}} $value | humanizeDuration {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletclientcertificateexpiration - summary: Kubelet client certificate is about to expire. - expr: kubelet_certificate_manager_client_ttl_seconds < 604800 - labels: - severity: {{ dig "KubeletClientCertificateExpiration" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletClientCertificateExpiration | default false) }} - - alert: KubeletClientCertificateExpiration - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Client certificate for Kubelet on node {{`{{`}} $labels.node {{`}}`}} expires in {{`{{`}} $value | humanizeDuration {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletclientcertificateexpiration - summary: Kubelet client certificate is about to expire. - expr: kubelet_certificate_manager_client_ttl_seconds < 86400 - labels: - severity: {{ dig "KubeletClientCertificateExpiration" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletServerCertificateExpiration | default false) }} - - alert: KubeletServerCertificateExpiration - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Server certificate for Kubelet on node {{`{{`}} $labels.node {{`}}`}} expires in {{`{{`}} $value | humanizeDuration {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletservercertificateexpiration - summary: Kubelet server certificate is about to expire. - expr: kubelet_certificate_manager_server_ttl_seconds < 604800 - labels: - severity: {{ dig "KubeletServerCertificateExpiration" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletServerCertificateExpiration | default false) }} - - alert: KubeletServerCertificateExpiration - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Server certificate for Kubelet on node {{`{{`}} $labels.node {{`}}`}} expires in {{`{{`}} $value | humanizeDuration {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletservercertificateexpiration - summary: Kubelet server certificate is about to expire. - expr: kubelet_certificate_manager_server_ttl_seconds < 86400 - labels: - severity: {{ dig "KubeletServerCertificateExpiration" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletClientCertificateRenewalErrors | default false) }} - - alert: KubeletClientCertificateRenewalErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Kubelet on node {{`{{`}} $labels.node {{`}}`}} has failed to renew its client certificate ({{`{{`}} $value | humanize {{`}}`}} errors in the last 5 minutes). - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletclientcertificaterenewalerrors - summary: Kubelet has failed to renew its client certificate. - expr: increase(kubelet_certificate_manager_client_expiration_renew_errors[5m]) > 0 - for: {{ dig "KubeletClientCertificateRenewalErrors" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeletClientCertificateRenewalErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeletServerCertificateRenewalErrors | default false) }} - - alert: KubeletServerCertificateRenewalErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Kubelet on node {{`{{`}} $labels.node {{`}}`}} has failed to renew its server certificate ({{`{{`}} $value | humanize {{`}}`}} errors in the last 5 minutes). - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletservercertificaterenewalerrors - summary: Kubelet has failed to renew its server certificate. - expr: increase(kubelet_server_expiration_renew_errors[5m]) > 0 - for: {{ dig "KubeletServerCertificateRenewalErrors" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeletServerCertificateRenewalErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if (include "exporter.kubelet.enabled" .)}} -{{- if not (.Values.defaultRules.disabled.KubeletDown | default false) }} - - alert: KubeletDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Kubelet has disappeared from Prometheus target discovery. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletdown - summary: Target disappeared from Prometheus target discovery. - expr: absent(up{job="{{ include "exporter.kubelet.jobName" . }}", metrics_path="/metrics"} == 1) - for: 15m - labels: - severity: {{ dig "KubeletDown" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml deleted file mode 100644 index d32f15139d..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml +++ /dev/null @@ -1,54 +0,0 @@ -{{- /* -Generated from 'kubernetes-system-scheduler' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeScheduler.enabled .Values.defaultRules.rules.kubeSchedulerAlerting }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-scheduler" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-system-scheduler - rules: -{{- if .Values.kubeScheduler.enabled }} -{{- if not (.Values.defaultRules.disabled.KubeSchedulerDown | default false) }} - - alert: KubeSchedulerDown - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeSchedulerAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeSchedulerAlerting | indent 8 }} -{{- end }} - description: KubeScheduler has disappeared from Prometheus target discovery. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeschedulerdown - summary: Target disappeared from Prometheus target discovery. - expr: absent(up{job="{{ include "exporter.kubeScheduler.jobName" . }}"} == 1) - for: 15m - labels: - severity: {{ dig "KubeSchedulerDown" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system.yaml deleted file mode 100644 index 929a6f43bd..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system.yaml +++ /dev/null @@ -1,87 +0,0 @@ -{{- /* -Generated from 'kubernetes-system' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesSystem }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: kubernetes-system - rules: -{{- if not (.Values.defaultRules.disabled.KubeVersionMismatch | default false) }} - - alert: KubeVersionMismatch - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: There are {{`{{`}} $value {{`}}`}} different semantic versions of Kubernetes components running. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeversionmismatch - summary: Different semantic versions of Kubernetes components running. - expr: count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}git_version, cluster) (label_replace(kubernetes_build_info{job!~"kube-dns|coredns"},"git_version","$1","git_version","(v[0-9]*.[0-9]*).*"))) > 1 - for: {{ dig "KubeVersionMismatch" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeVersionMismatch" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.KubeClientErrors | default false) }} - - alert: KubeClientErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} -{{- end }} - description: Kubernetes API server client '{{`{{`}} $labels.job {{`}}`}}/{{`{{`}} $labels.instance {{`}}`}}' is experiencing {{`{{`}} $value | humanizePercentage {{`}}`}} errors.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeclienterrors - summary: Kubernetes API server client is experiencing errors. - expr: |- - (sum(rate(rest_client_requests_total{job="apiserver",code=~"5.."}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, job, namespace) - / - sum(rate(rest_client_requests_total{job="apiserver"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, job, namespace)) - > 0.01 - for: {{ dig "KubeClientErrors" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "KubeClientErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-exporter.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-exporter.rules.yaml deleted file mode 100644 index aeaa80231c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-exporter.rules.yaml +++ /dev/null @@ -1,188 +0,0 @@ -{{- /* -Generated from 'node-exporter.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.nodeExporterRecording }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "node-exporter.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: node-exporter.rules - rules: - - expr: |- - count without (cpu, mode) ( - node_cpu_seconds_total{job="node-exporter",mode="idle"} - ) - record: instance:node_num_cpu:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - 1 - avg without (cpu) ( - sum without (mode) (rate(node_cpu_seconds_total{job="node-exporter", mode=~"idle|iowait|steal"}[5m])) - ) - record: instance:node_cpu_utilisation:rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - ( - node_load1{job="node-exporter"} - / - instance:node_num_cpu:sum{job="node-exporter"} - ) - record: instance:node_load1_per_cpu:ratio - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - 1 - ( - ( - node_memory_MemAvailable_bytes{job="node-exporter"} - or - ( - node_memory_Buffers_bytes{job="node-exporter"} - + - node_memory_Cached_bytes{job="node-exporter"} - + - node_memory_MemFree_bytes{job="node-exporter"} - + - node_memory_Slab_bytes{job="node-exporter"} - ) - ) - / - node_memory_MemTotal_bytes{job="node-exporter"} - ) - record: instance:node_memory_utilisation:ratio - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: rate(node_vmstat_pgmajfault{job="node-exporter"}[5m]) - record: instance:node_vmstat_pgmajfault:rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: rate(node_disk_io_time_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) - record: instance_device:node_disk_io_time_seconds:rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: rate(node_disk_io_time_weighted_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) - record: instance_device:node_disk_io_time_weighted_seconds:rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum without (device) ( - rate(node_network_receive_bytes_total{job="node-exporter", device!="lo"}[5m]) - ) - record: instance:node_network_receive_bytes_excluding_lo:rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum without (device) ( - rate(node_network_transmit_bytes_total{job="node-exporter", device!="lo"}[5m]) - ) - record: instance:node_network_transmit_bytes_excluding_lo:rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum without (device) ( - rate(node_network_receive_drop_total{job="node-exporter", device!="lo"}[5m]) - ) - record: instance:node_network_receive_drop_excluding_lo:rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum without (device) ( - rate(node_network_transmit_drop_total{job="node-exporter", device!="lo"}[5m]) - ) - record: instance:node_network_transmit_drop_excluding_lo:rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-exporter.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-exporter.yaml deleted file mode 100644 index 80bfd9bf36..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-exporter.yaml +++ /dev/null @@ -1,801 +0,0 @@ -{{- /* -Generated from 'node-exporter' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.nodeExporterAlerting }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "node-exporter" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: node-exporter - rules: -{{- if not (.Values.defaultRules.disabled.NodeFilesystemSpaceFillingUp | default false) }} - - alert: NodeFilesystemSpaceFillingUp - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available space left and is filling up. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemspacefillingup - summary: Filesystem is predicted to run out of space within the next 24 hours. - expr: |- - ( - node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 15 - and - predict_linear(node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""}[6h], 24*60*60) < 0 - and - node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 - ) - for: {{ dig "NodeFilesystemSpaceFillingUp" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFilesystemSpaceFillingUp" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFilesystemSpaceFillingUp | default false) }} - - alert: NodeFilesystemSpaceFillingUp - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available space left and is filling up fast. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemspacefillingup - summary: Filesystem is predicted to run out of space within the next 4 hours. - expr: |- - ( - node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 10 - and - predict_linear(node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""}[6h], 4*60*60) < 0 - and - node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 - ) - for: {{ dig "NodeFilesystemSpaceFillingUp" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFilesystemSpaceFillingUp" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFilesystemAlmostOutOfSpace | default false) }} - - alert: NodeFilesystemAlmostOutOfSpace - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available space left. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemalmostoutofspace - summary: Filesystem has less than 5% space left. - expr: |- - ( - node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 5 - and - node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 - ) - for: {{ dig "NodeFilesystemAlmostOutOfSpace" "for" "30m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFilesystemAlmostOutOfSpace" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFilesystemAlmostOutOfSpace | default false) }} - - alert: NodeFilesystemAlmostOutOfSpace - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available space left. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemalmostoutofspace - summary: Filesystem has less than 3% space left. - expr: |- - ( - node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 3 - and - node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 - ) - for: {{ dig "NodeFilesystemAlmostOutOfSpace" "for" "30m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFilesystemAlmostOutOfSpace" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFilesystemFilesFillingUp | default false) }} - - alert: NodeFilesystemFilesFillingUp - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available inodes left and is filling up. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemfilesfillingup - summary: Filesystem is predicted to run out of inodes within the next 24 hours. - expr: |- - ( - node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 40 - and - predict_linear(node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""}[6h], 24*60*60) < 0 - and - node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 - ) - for: {{ dig "NodeFilesystemFilesFillingUp" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFilesystemFilesFillingUp" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFilesystemFilesFillingUp | default false) }} - - alert: NodeFilesystemFilesFillingUp - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available inodes left and is filling up fast. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemfilesfillingup - summary: Filesystem is predicted to run out of inodes within the next 4 hours. - expr: |- - ( - node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 20 - and - predict_linear(node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""}[6h], 4*60*60) < 0 - and - node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 - ) - for: {{ dig "NodeFilesystemFilesFillingUp" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFilesystemFilesFillingUp" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFilesystemAlmostOutOfFiles | default false) }} - - alert: NodeFilesystemAlmostOutOfFiles - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available inodes left. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemalmostoutoffiles - summary: Filesystem has less than 5% inodes left. - expr: |- - ( - node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 5 - and - node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 - ) - for: {{ dig "NodeFilesystemAlmostOutOfFiles" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFilesystemAlmostOutOfFiles" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFilesystemAlmostOutOfFiles | default false) }} - - alert: NodeFilesystemAlmostOutOfFiles - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available inodes left. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemalmostoutoffiles - summary: Filesystem has less than 3% inodes left. - expr: |- - ( - node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 3 - and - node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 - ) - for: {{ dig "NodeFilesystemAlmostOutOfFiles" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFilesystemAlmostOutOfFiles" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeNetworkReceiveErrs | default false) }} - - alert: NodeNetworkReceiveErrs - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: '{{`{{`}} $labels.instance {{`}}`}} interface {{`{{`}} $labels.device {{`}}`}} has encountered {{`{{`}} printf "%.0f" $value {{`}}`}} receive errors in the last two minutes.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodenetworkreceiveerrs - summary: Network interface is reporting many receive errors. - expr: rate(node_network_receive_errs_total{job="node-exporter"}[2m]) / rate(node_network_receive_packets_total{job="node-exporter"}[2m]) > 0.01 - for: {{ dig "NodeNetworkReceiveErrs" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeNetworkReceiveErrs" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeNetworkTransmitErrs | default false) }} - - alert: NodeNetworkTransmitErrs - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: '{{`{{`}} $labels.instance {{`}}`}} interface {{`{{`}} $labels.device {{`}}`}} has encountered {{`{{`}} printf "%.0f" $value {{`}}`}} transmit errors in the last two minutes.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodenetworktransmiterrs - summary: Network interface is reporting many transmit errors. - expr: rate(node_network_transmit_errs_total{job="node-exporter"}[2m]) / rate(node_network_transmit_packets_total{job="node-exporter"}[2m]) > 0.01 - for: {{ dig "NodeNetworkTransmitErrs" "for" "1h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeNetworkTransmitErrs" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeHighNumberConntrackEntriesUsed | default false) }} - - alert: NodeHighNumberConntrackEntriesUsed - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of conntrack entries are used.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodehighnumberconntrackentriesused - summary: Number of conntrack are getting close to the limit. - expr: (node_nf_conntrack_entries{job="node-exporter"} / node_nf_conntrack_entries_limit) > 0.75 - labels: - severity: {{ dig "NodeHighNumberConntrackEntriesUsed" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeTextFileCollectorScrapeError | default false) }} - - alert: NodeTextFileCollectorScrapeError - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Node Exporter text file collector on {{`{{`}} $labels.instance {{`}}`}} failed to scrape. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodetextfilecollectorscrapeerror - summary: Node Exporter text file collector failed to scrape. - expr: node_textfile_scrape_error{job="node-exporter"} == 1 - labels: - severity: {{ dig "NodeTextFileCollectorScrapeError" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeClockSkewDetected | default false) }} - - alert: NodeClockSkewDetected - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Clock at {{`{{`}} $labels.instance {{`}}`}} is out of sync by more than 0.05s. Ensure NTP is configured correctly on this host. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodeclockskewdetected - summary: Clock skew detected. - expr: |- - ( - node_timex_offset_seconds{job="node-exporter"} > 0.05 - and - deriv(node_timex_offset_seconds{job="node-exporter"}[5m]) >= 0 - ) - or - ( - node_timex_offset_seconds{job="node-exporter"} < -0.05 - and - deriv(node_timex_offset_seconds{job="node-exporter"}[5m]) <= 0 - ) - for: {{ dig "NodeClockSkewDetected" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeClockSkewDetected" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeClockNotSynchronising | default false) }} - - alert: NodeClockNotSynchronising - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Clock at {{`{{`}} $labels.instance {{`}}`}} is not synchronising. Ensure NTP is configured on this host. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodeclocknotsynchronising - summary: Clock not synchronising. - expr: |- - min_over_time(node_timex_sync_status{job="node-exporter"}[5m]) == 0 - and - node_timex_maxerror_seconds{job="node-exporter"} >= 16 - for: {{ dig "NodeClockNotSynchronising" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeClockNotSynchronising" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeRAIDDegraded | default false) }} - - alert: NodeRAIDDegraded - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: RAID array '{{`{{`}} $labels.device {{`}}`}}' at {{`{{`}} $labels.instance {{`}}`}} is in degraded state due to one or more disks failures. Number of spare drives is insufficient to fix issue automatically. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/noderaiddegraded - summary: RAID Array is degraded. - expr: node_md_disks_required{job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"} - ignoring (state) (node_md_disks{state="active",job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}) > 0 - for: {{ dig "NodeRAIDDegraded" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeRAIDDegraded" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeRAIDDiskFailure | default false) }} - - alert: NodeRAIDDiskFailure - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: At least one device in RAID array at {{`{{`}} $labels.instance {{`}}`}} failed. Array '{{`{{`}} $labels.device {{`}}`}}' needs attention and possibly a disk swap. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/noderaiddiskfailure - summary: Failed device in RAID array. - expr: node_md_disks{state="failed",job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"} > 0 - labels: - severity: {{ dig "NodeRAIDDiskFailure" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFileDescriptorLimit | default false) }} - - alert: NodeFileDescriptorLimit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: File descriptors limit at {{`{{`}} $labels.instance {{`}}`}} is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}%. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefiledescriptorlimit - summary: Kernel is predicted to exhaust file descriptors limit soon. - expr: |- - ( - node_filefd_allocated{job="node-exporter"} * 100 / node_filefd_maximum{job="node-exporter"} > 70 - ) - for: {{ dig "NodeFileDescriptorLimit" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFileDescriptorLimit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeFileDescriptorLimit | default false) }} - - alert: NodeFileDescriptorLimit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: File descriptors limit at {{`{{`}} $labels.instance {{`}}`}} is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}%. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefiledescriptorlimit - summary: Kernel is predicted to exhaust file descriptors limit soon. - expr: |- - ( - node_filefd_allocated{job="node-exporter"} * 100 / node_filefd_maximum{job="node-exporter"} > 90 - ) - for: {{ dig "NodeFileDescriptorLimit" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeFileDescriptorLimit" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeCPUHighUsage | default false) }} - - alert: NodeCPUHighUsage - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: 'CPU usage at {{`{{`}} $labels.instance {{`}}`}} has been above 90% for the last 15 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}%. - - ' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodecpuhighusage - summary: High CPU usage. - expr: sum without(mode) (avg without (cpu) (rate(node_cpu_seconds_total{job="node-exporter", mode!="idle"}[2m]))) * 100 > 90 - for: {{ dig "NodeCPUHighUsage" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeCPUHighUsage" "severity" "info" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeSystemSaturation | default false) }} - - alert: NodeSystemSaturation - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: 'System load per core at {{`{{`}} $labels.instance {{`}}`}} has been above 2 for the last 15 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}. - - This might indicate this instance resources saturation and can cause it becoming unresponsive. - - ' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodesystemsaturation - summary: System saturated, load per core is very high. - expr: |- - node_load1{job="node-exporter"} - / count without (cpu, mode) (node_cpu_seconds_total{job="node-exporter", mode="idle"}) > 2 - for: {{ dig "NodeSystemSaturation" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeSystemSaturation" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeMemoryMajorPagesFaults | default false) }} - - alert: NodeMemoryMajorPagesFaults - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: 'Memory major pages are occurring at very high rate at {{`{{`}} $labels.instance {{`}}`}}, 500 major page faults per second for the last 15 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}. - - Please check that there is enough memory available at this instance. - - ' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodememorymajorpagesfaults - summary: Memory major page faults are occurring at very high rate. - expr: rate(node_vmstat_pgmajfault{job="node-exporter"}[5m]) > 500 - for: {{ dig "NodeMemoryMajorPagesFaults" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeMemoryMajorPagesFaults" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeMemoryHighUtilization | default false) }} - - alert: NodeMemoryHighUtilization - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: 'Memory is filling up at {{`{{`}} $labels.instance {{`}}`}}, has been above 90% for the last 15 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}%. - - ' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodememoryhighutilization - summary: Host is running out of memory. - expr: 100 - (node_memory_MemAvailable_bytes{job="node-exporter"} / node_memory_MemTotal_bytes{job="node-exporter"} * 100) > 90 - for: {{ dig "NodeMemoryHighUtilization" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeMemoryHighUtilization" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeDiskIOSaturation | default false) }} - - alert: NodeDiskIOSaturation - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: 'Disk IO queue (aqu-sq) is high on {{`{{`}} $labels.device {{`}}`}} at {{`{{`}} $labels.instance {{`}}`}}, has been above 10 for the last 30 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}. - - This symptom might indicate disk saturation. - - ' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodediskiosaturation - summary: Disk IO queue is high. - expr: rate(node_disk_io_time_weighted_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) > 10 - for: {{ dig "NodeDiskIOSaturation" "for" "30m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeDiskIOSaturation" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeSystemdServiceFailed | default false) }} - - alert: NodeSystemdServiceFailed - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Systemd service {{`{{`}} $labels.name {{`}}`}} has entered failed state at {{`{{`}} $labels.instance {{`}}`}} - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodesystemdservicefailed - summary: Systemd service has entered failed state. - expr: node_systemd_unit_state{job="node-exporter", state="failed"} == 1 - for: {{ dig "NodeSystemdServiceFailed" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeSystemdServiceFailed" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.NodeBondingDegraded | default false) }} - - alert: NodeBondingDegraded - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} -{{- end }} - description: Bonding interface {{`{{`}} $labels.master {{`}}`}} on {{`{{`}} $labels.instance {{`}}`}} is in degraded state due to one or more slave failures. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodebondingdegraded - summary: Bonding interface is degraded - expr: (node_bonding_slaves - node_bonding_active) != 0 - for: {{ dig "NodeBondingDegraded" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeBondingDegraded" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-network.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-network.yaml deleted file mode 100644 index 16690ee313..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node-network.yaml +++ /dev/null @@ -1,55 +0,0 @@ -{{- /* -Generated from 'node-network' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.network }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "node-network" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: node-network - rules: -{{- if not (.Values.defaultRules.disabled.NodeNetworkInterfaceFlapping | default false) }} - - alert: NodeNetworkInterfaceFlapping - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.network }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.network | indent 8 }} -{{- end }} - description: Network interface "{{`{{`}} $labels.device {{`}}`}}" changing its up status often on node-exporter {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod {{`}}`}} - runbook_url: {{ .Values.defaultRules.runbookUrl }}/general/nodenetworkinterfaceflapping - summary: Network interface is often changing its status - expr: changes(node_network_up{job="node-exporter",device!~"veth.+"}[2m]) > 2 - for: {{ dig "NodeNetworkInterfaceFlapping" "for" "2m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "NodeNetworkInterfaceFlapping" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.network }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.network }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node.rules.yaml deleted file mode 100644 index 0bf9b8653e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/node.rules.yaml +++ /dev/null @@ -1,109 +0,0 @@ -{{- /* -Generated from 'node.rules' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.node }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "node.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: node.rules - rules: - - expr: |- - topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node, namespace, pod) ( - label_replace(kube_pod_info{job="{{ $kubeStateMetricsJob }}",node!=""}, "pod", "$1", "pod", "(.*)") - )) - record: 'node_namespace_pod:kube_pod_info:' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) ( - node_cpu_seconds_total{mode="idle",job="node-exporter"} - * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) - topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, node_namespace_pod:kube_pod_info:) - ) - record: node:node_num_cpu:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum( - node_memory_MemAvailable_bytes{job="node-exporter"} or - ( - node_memory_Buffers_bytes{job="node-exporter"} + - node_memory_Cached_bytes{job="node-exporter"} + - node_memory_MemFree_bytes{job="node-exporter"} + - node_memory_Slab_bytes{job="node-exporter"} - ) - ) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - record: :node_memory_MemAvailable_bytes:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) ( - sum without (mode) ( - rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal",job="node-exporter"}[5m]) - ) - ) - record: node:node_cpu_utilization:ratio_rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) ( - node:node_cpu_utilization:ratio_rate5m - ) - record: cluster:node_cpu:ratio_rate5m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/prometheus-operator.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/prometheus-operator.yaml deleted file mode 100644 index cb5c495877..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/prometheus-operator.yaml +++ /dev/null @@ -1,253 +0,0 @@ -{{- /* -Generated from 'prometheus-operator' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.prometheusOperator }} -{{- $operatorJob := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "operator" }} -{{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "prometheus-operator" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: prometheus-operator - rules: -{{- if not (.Values.defaultRules.disabled.PrometheusOperatorListErrors | default false) }} - - alert: PrometheusOperatorListErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} -{{- end }} - description: Errors while performing List operations in controller {{`{{`}}$labels.controller{{`}}`}} in {{`{{`}}$labels.namespace{{`}}`}} namespace. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorlisterrors - summary: Errors while performing list operations in controller. - expr: (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_list_operations_failed_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[10m])) / sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_list_operations_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[10m]))) > 0.4 - for: {{ dig "PrometheusOperatorListErrors" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOperatorListErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusOperatorWatchErrors | default false) }} - - alert: PrometheusOperatorWatchErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} -{{- end }} - description: Errors while performing watch operations in controller {{`{{`}}$labels.controller{{`}}`}} in {{`{{`}}$labels.namespace{{`}}`}} namespace. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorwatcherrors - summary: Errors while performing watch operations in controller. - expr: (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_watch_operations_failed_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m])) / sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_watch_operations_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) > 0.4 - for: {{ dig "PrometheusOperatorWatchErrors" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOperatorWatchErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusOperatorSyncFailed | default false) }} - - alert: PrometheusOperatorSyncFailed - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} -{{- end }} - description: Controller {{`{{`}} $labels.controller {{`}}`}} in {{`{{`}} $labels.namespace {{`}}`}} namespace fails to reconcile {{`{{`}} $value {{`}}`}} objects. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorsyncfailed - summary: Last controller reconciliation failed - expr: min_over_time(prometheus_operator_syncs{status="failed",job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusOperatorSyncFailed" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOperatorSyncFailed" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusOperatorReconcileErrors | default false) }} - - alert: PrometheusOperatorReconcileErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} -{{- end }} - description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of reconciling operations failed for {{`{{`}} $labels.controller {{`}}`}} controller in {{`{{`}} $labels.namespace {{`}}`}} namespace.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorreconcileerrors - summary: Errors while reconciling objects. - expr: (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_reconcile_errors_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) / (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_reconcile_operations_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) > 0.1 - for: {{ dig "PrometheusOperatorReconcileErrors" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOperatorReconcileErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusOperatorStatusUpdateErrors | default false) }} - - alert: PrometheusOperatorStatusUpdateErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} -{{- end }} - description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of status update operations failed for {{`{{`}} $labels.controller {{`}}`}} controller in {{`{{`}} $labels.namespace {{`}}`}} namespace.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorstatusupdateerrors - summary: Errors while updating objects status. - expr: (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_status_update_errors_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) / (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_status_update_operations_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) > 0.1 - for: {{ dig "PrometheusOperatorStatusUpdateErrors" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOperatorStatusUpdateErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusOperatorNodeLookupErrors | default false) }} - - alert: PrometheusOperatorNodeLookupErrors - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} -{{- end }} - description: Errors while reconciling Prometheus in {{`{{`}} $labels.namespace {{`}}`}} Namespace. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatornodelookuperrors - summary: Errors while reconciling Prometheus. - expr: rate(prometheus_operator_node_address_lookup_errors_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]) > 0.1 - for: {{ dig "PrometheusOperatorNodeLookupErrors" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOperatorNodeLookupErrors" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusOperatorNotReady | default false) }} - - alert: PrometheusOperatorNotReady - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} -{{- end }} - description: Prometheus operator in {{`{{`}} $labels.namespace {{`}}`}} namespace isn't ready to reconcile {{`{{`}} $labels.controller {{`}}`}} resources. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatornotready - summary: Prometheus operator not ready - expr: min by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (max_over_time(prometheus_operator_ready{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]) == 0) - for: {{ dig "PrometheusOperatorNotReady" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOperatorNotReady" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusOperatorRejectedResources | default false) }} - - alert: PrometheusOperatorRejectedResources - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} -{{- end }} - description: Prometheus operator in {{`{{`}} $labels.namespace {{`}}`}} namespace rejected {{`{{`}} printf "%0.0f" $value {{`}}`}} {{`{{`}} $labels.controller {{`}}`}}/{{`{{`}} $labels.resource {{`}}`}} resources. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorrejectedresources - summary: Resources rejected by Prometheus operator - expr: min_over_time(prometheus_operator_managed_resources{state="rejected",job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusOperatorRejectedResources" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOperatorRejectedResources" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/prometheus.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/prometheus.yaml deleted file mode 100644 index 0cc617ff77..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/prometheus.yaml +++ /dev/null @@ -1,735 +0,0 @@ -{{- /* -Generated from 'prometheus' group from https://github.com/prometheus-operator/kube-prometheus.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.prometheus }} -{{- $prometheusJob := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "prometheus" }} -{{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "prometheus" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: prometheus - rules: -{{- if not (.Values.defaultRules.disabled.PrometheusBadConfig | default false) }} - - alert: PrometheusBadConfig - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed to reload its configuration. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusbadconfig - summary: Failed Prometheus configuration reload. - expr: |- - # Without max_over_time, failed scrapes could create false negatives, see - # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. - max_over_time(prometheus_config_last_reload_successful{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) == 0 - for: {{ dig "PrometheusBadConfig" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusBadConfig" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusSDRefreshFailure | default false) }} - - alert: PrometheusSDRefreshFailure - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed to refresh SD with mechanism {{`{{`}}$labels.mechanism{{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheussdrefreshfailure - summary: Failed Prometheus SD refresh. - expr: increase(prometheus_sd_refresh_failures_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[10m]) > 0 - for: {{ dig "PrometheusSDRefreshFailure" "for" "20m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusSDRefreshFailure" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusKubernetesListWatchFailures | default false) }} - - alert: PrometheusKubernetesListWatchFailures - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Kubernetes service discovery of Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is experiencing {{`{{`}} printf "%.0f" $value {{`}}`}} failures with LIST/WATCH requests to the Kubernetes API in the last 5 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheuskuberneteslistwatchfailures - summary: Requests in Kubernetes SD are failing. - expr: increase(prometheus_sd_kubernetes_failures_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusKubernetesListWatchFailures" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusKubernetesListWatchFailures" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusNotificationQueueRunningFull | default false) }} - - alert: PrometheusNotificationQueueRunningFull - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Alert notification queue of Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is running full. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusnotificationqueuerunningfull - summary: Prometheus alert notification queue predicted to run full in less than 30m. - expr: |- - # Without min_over_time, failed scrapes could create false negatives, see - # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. - ( - predict_linear(prometheus_notifications_queue_length{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m], 60 * 30) - > - min_over_time(prometheus_notifications_queue_capacity{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) - ) - for: {{ dig "PrometheusNotificationQueueRunningFull" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusNotificationQueueRunningFull" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusErrorSendingAlertsToSomeAlertmanagers | default false) }} - - alert: PrometheusErrorSendingAlertsToSomeAlertmanagers - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: '{{`{{`}} printf "%.1f" $value {{`}}`}}% errors while sending alerts from Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} to Alertmanager {{`{{`}}$labels.alertmanager{{`}}`}}.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheuserrorsendingalertstosomealertmanagers - summary: Prometheus has encountered more than 1% errors sending alerts to a specific Alertmanager. - expr: |- - ( - rate(prometheus_notifications_errors_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) - / - rate(prometheus_notifications_sent_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) - ) - * 100 - > 1 - for: {{ dig "PrometheusErrorSendingAlertsToSomeAlertmanagers" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusErrorSendingAlertsToSomeAlertmanagers" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusNotConnectedToAlertmanagers | default false) }} - - alert: PrometheusNotConnectedToAlertmanagers - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is not connected to any Alertmanagers. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusnotconnectedtoalertmanagers - summary: Prometheus is not connected to any Alertmanagers. - expr: |- - # Without max_over_time, failed scrapes could create false negatives, see - # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. - max_over_time(prometheus_notifications_alertmanagers_discovered{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) < 1 - for: {{ dig "PrometheusNotConnectedToAlertmanagers" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusNotConnectedToAlertmanagers" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusTSDBReloadsFailing | default false) }} - - alert: PrometheusTSDBReloadsFailing - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has detected {{`{{`}}$value | humanize{{`}}`}} reload failures over the last 3h. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheustsdbreloadsfailing - summary: Prometheus has issues reloading blocks from disk. - expr: increase(prometheus_tsdb_reloads_failures_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[3h]) > 0 - for: {{ dig "PrometheusTSDBReloadsFailing" "for" "4h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusTSDBReloadsFailing" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusTSDBCompactionsFailing | default false) }} - - alert: PrometheusTSDBCompactionsFailing - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has detected {{`{{`}}$value | humanize{{`}}`}} compaction failures over the last 3h. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheustsdbcompactionsfailing - summary: Prometheus has issues compacting blocks. - expr: increase(prometheus_tsdb_compactions_failed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[3h]) > 0 - for: {{ dig "PrometheusTSDBCompactionsFailing" "for" "4h" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusTSDBCompactionsFailing" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusNotIngestingSamples | default false) }} - - alert: PrometheusNotIngestingSamples - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is not ingesting samples. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusnotingestingsamples - summary: Prometheus is not ingesting samples. - expr: |- - ( - sum without(type) (rate(prometheus_tsdb_head_samples_appended_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m])) <= 0 - and - ( - sum without(scrape_job) (prometheus_target_metadata_cache_entries{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}) > 0 - or - sum without(rule_group) (prometheus_rule_group_rules{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}) > 0 - ) - ) - for: {{ dig "PrometheusNotIngestingSamples" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusNotIngestingSamples" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusDuplicateTimestamps | default false) }} - - alert: PrometheusDuplicateTimestamps - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is dropping {{`{{`}} printf "%.4g" $value {{`}}`}} samples/s with different values but duplicated timestamp. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusduplicatetimestamps - summary: Prometheus is dropping samples with duplicate timestamps. - expr: rate(prometheus_target_scrapes_sample_duplicate_timestamp_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusDuplicateTimestamps" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusDuplicateTimestamps" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusOutOfOrderTimestamps | default false) }} - - alert: PrometheusOutOfOrderTimestamps - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is dropping {{`{{`}} printf "%.4g" $value {{`}}`}} samples/s with timestamps arriving out of order. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusoutofordertimestamps - summary: Prometheus drops samples with out-of-order timestamps. - expr: rate(prometheus_target_scrapes_sample_out_of_order_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusOutOfOrderTimestamps" "for" "10m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusOutOfOrderTimestamps" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusRemoteStorageFailures | default false) }} - - alert: PrometheusRemoteStorageFailures - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} failed to send {{`{{`}} printf "%.1f" $value {{`}}`}}% of the samples to {{`{{`}} $labels.remote_name{{`}}`}}:{{`{{`}} $labels.url {{`}}`}} - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusremotestoragefailures - summary: Prometheus fails to send samples to remote storage. - expr: |- - ( - (rate(prometheus_remote_storage_failed_samples_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m])) - / - ( - (rate(prometheus_remote_storage_failed_samples_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m])) - + - (rate(prometheus_remote_storage_succeeded_samples_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) or rate(prometheus_remote_storage_samples_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m])) - ) - ) - * 100 - > 1 - for: {{ dig "PrometheusRemoteStorageFailures" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusRemoteStorageFailures" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusRemoteWriteBehind | default false) }} - - alert: PrometheusRemoteWriteBehind - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} remote write is {{`{{`}} printf "%.1f" $value {{`}}`}}s behind for {{`{{`}} $labels.remote_name{{`}}`}}:{{`{{`}} $labels.url {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusremotewritebehind - summary: Prometheus remote write is behind. - expr: |- - # Without max_over_time, failed scrapes could create false negatives, see - # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. - ( - max_over_time(prometheus_remote_storage_highest_timestamp_in_seconds{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) - - ignoring(remote_name, url) group_right - max_over_time(prometheus_remote_storage_queue_highest_sent_timestamp_seconds{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) - ) - > 120 - for: {{ dig "PrometheusRemoteWriteBehind" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusRemoteWriteBehind" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusRemoteWriteDesiredShards | default false) }} - - alert: PrometheusRemoteWriteDesiredShards - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} remote write desired shards calculation wants to run {{`{{`}} $value {{`}}`}} shards for queue {{`{{`}} $labels.remote_name{{`}}`}}:{{`{{`}} $labels.url {{`}}`}}, which is more than the max of {{`{{`}} printf `prometheus_remote_storage_shards_max{instance="%s",job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}` $labels.instance | query | first | value {{`}}`}}. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusremotewritedesiredshards - summary: Prometheus remote write desired shards calculation wants to run more than configured max shards. - expr: |- - # Without max_over_time, failed scrapes could create false negatives, see - # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. - ( - max_over_time(prometheus_remote_storage_shards_desired{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) - > - max_over_time(prometheus_remote_storage_shards_max{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) - ) - for: {{ dig "PrometheusRemoteWriteDesiredShards" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusRemoteWriteDesiredShards" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusRuleFailures | default false) }} - - alert: PrometheusRuleFailures - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed to evaluate {{`{{`}} printf "%.0f" $value {{`}}`}} rules in the last 5m. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusrulefailures - summary: Prometheus is failing rule evaluations. - expr: increase(prometheus_rule_evaluation_failures_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusRuleFailures" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusRuleFailures" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusMissingRuleEvaluations | default false) }} - - alert: PrometheusMissingRuleEvaluations - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has missed {{`{{`}} printf "%.0f" $value {{`}}`}} rule group evaluations in the last 5m. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusmissingruleevaluations - summary: Prometheus is missing rule evaluations due to slow rule group evaluation. - expr: increase(prometheus_rule_group_iterations_missed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusMissingRuleEvaluations" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusMissingRuleEvaluations" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusTargetLimitHit | default false) }} - - alert: PrometheusTargetLimitHit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has dropped {{`{{`}} printf "%.0f" $value {{`}}`}} targets because the number of targets exceeded the configured target_limit. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheustargetlimithit - summary: Prometheus has dropped targets because some scrape configs have exceeded the targets limit. - expr: increase(prometheus_target_scrape_pool_exceeded_target_limit_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusTargetLimitHit" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusTargetLimitHit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusLabelLimitHit | default false) }} - - alert: PrometheusLabelLimitHit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has dropped {{`{{`}} printf "%.0f" $value {{`}}`}} targets because some samples exceeded the configured label_limit, label_name_length_limit or label_value_length_limit. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheuslabellimithit - summary: Prometheus has dropped targets because some scrape configs have exceeded the labels limit. - expr: increase(prometheus_target_scrape_pool_exceeded_label_limits_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusLabelLimitHit" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusLabelLimitHit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusScrapeBodySizeLimitHit | default false) }} - - alert: PrometheusScrapeBodySizeLimitHit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed {{`{{`}} printf "%.0f" $value {{`}}`}} scrapes in the last 5m because some targets exceeded the configured body_size_limit. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusscrapebodysizelimithit - summary: Prometheus has dropped some targets that exceeded body size limit. - expr: increase(prometheus_target_scrapes_exceeded_body_size_limit_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusScrapeBodySizeLimitHit" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusScrapeBodySizeLimitHit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusScrapeSampleLimitHit | default false) }} - - alert: PrometheusScrapeSampleLimitHit - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed {{`{{`}} printf "%.0f" $value {{`}}`}} scrapes in the last 5m because some targets exceeded the configured sample_limit. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusscrapesamplelimithit - summary: Prometheus has failed scrapes that have exceeded the configured sample limit. - expr: increase(prometheus_target_scrapes_exceeded_sample_limit_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 - for: {{ dig "PrometheusScrapeSampleLimitHit" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusScrapeSampleLimitHit" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusTargetSyncFailure | default false) }} - - alert: PrometheusTargetSyncFailure - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: '{{`{{`}} printf "%.0f" $value {{`}}`}} targets in Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} have failed to sync because invalid configuration was supplied.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheustargetsyncfailure - summary: Prometheus has failed to sync targets. - expr: increase(prometheus_target_sync_failed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[30m]) > 0 - for: {{ dig "PrometheusTargetSyncFailure" "for" "5m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusTargetSyncFailure" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusHighQueryLoad | default false) }} - - alert: PrometheusHighQueryLoad - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} query API has less than 20% available capacity in its query engine for the last 15 minutes. - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheushighqueryload - summary: Prometheus is reaching its maximum capacity serving concurrent requests. - expr: avg_over_time(prometheus_engine_queries{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) / max_over_time(prometheus_engine_queries_concurrent_max{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0.8 - for: {{ dig "PrometheusHighQueryLoad" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusHighQueryLoad" "severity" "warning" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- if not (.Values.defaultRules.disabled.PrometheusErrorSendingAlertsToAnyAlertmanager | default false) }} - - alert: PrometheusErrorSendingAlertsToAnyAlertmanager - annotations: -{{- if .Values.defaultRules.additionalRuleAnnotations }} -{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} -{{- end }} -{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} -{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} -{{- end }} - description: '{{`{{`}} printf "%.1f" $value {{`}}`}}% minimum errors while sending alerts from Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} to any Alertmanager.' - runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheuserrorsendingalertstoanyalertmanager - summary: Prometheus encounters more than 3% errors sending alerts to any Alertmanager. - expr: |- - min without (alertmanager) ( - rate(prometheus_notifications_errors_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}",alertmanager!~``}[5m]) - / - rate(prometheus_notifications_sent_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}",alertmanager!~``}[5m]) - ) - * 100 - > 3 - for: {{ dig "PrometheusErrorSendingAlertsToAnyAlertmanager" "for" "15m" .Values.customRules }} - {{- with .Values.defaultRules.keepFiringFor }} - keep_firing_for: "{{ . }}" - {{- end }} - labels: - severity: {{ dig "PrometheusErrorSendingAlertsToAnyAlertmanager" "severity" "critical" .Values.customRules }} - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/windows.node.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/windows.node.rules.yaml deleted file mode 100644 index 7c25553861..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/windows.node.rules.yaml +++ /dev/null @@ -1,301 +0,0 @@ -{{- /* -Generated from 'windows.node.rules' group from https://github.com/kubernetes-monitoring/kubernetes-mixin.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.windowsMonitoring.enabled .Values.defaultRules.rules.windows }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "windows.node.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: windows.node.rules - rules: - - expr: |- - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) ( - windows_system_system_up_time{job="windows-exporter"} - ) - record: node:windows_node:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, core) ( - windows_cpu_time_total{job="windows-exporter"} - )) - record: node:windows_node_num_cpu:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: 1 - avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(windows_cpu_time_total{job="windows-exporter",mode="idle"}[1m])) - record: :windows_node_cpu_utilisation:avg1m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - 1 - avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( - rate(windows_cpu_time_total{job="windows-exporter",mode="idle"}[1m]) - ) - record: node:windows_node_cpu_utilisation:avg1m - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - 1 - - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (windows_memory_available_bytes{job="windows-exporter"}) - / - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (windows_os_visible_memory_bytes{job="windows-exporter"}) - record: ':windows_node_memory_utilisation:' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (windows_memory_available_bytes{job="windows-exporter"} + windows_memory_cache_bytes{job="windows-exporter"}) - record: :windows_node_memory_MemFreeCached_bytes:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: (windows_memory_cache_bytes{job="windows-exporter"} + windows_memory_modified_page_list_bytes{job="windows-exporter"} + windows_memory_standby_cache_core_bytes{job="windows-exporter"} + windows_memory_standby_cache_normal_priority_bytes{job="windows-exporter"} + windows_memory_standby_cache_reserve_bytes{job="windows-exporter"}) - record: node:windows_node_memory_totalCached_bytes:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (windows_os_visible_memory_bytes{job="windows-exporter"}) - record: :windows_node_memory_MemTotal_bytes:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( - (windows_memory_available_bytes{job="windows-exporter"}) - ) - record: node:windows_node_memory_bytes_available:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( - windows_os_visible_memory_bytes{job="windows-exporter"} - ) - record: node:windows_node_memory_bytes_total:sum - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - (node:windows_node_memory_bytes_total:sum - node:windows_node_memory_bytes_available:sum) - / - scalar(sum(node:windows_node_memory_bytes_total:sum)) - record: node:windows_node_memory_utilisation:ratio - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: 1 - (node:windows_node_memory_bytes_available:sum / node:windows_node_memory_bytes_total:sum) - record: 'node:windows_node_memory_utilisation:' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: irate(windows_memory_swap_page_operations_total{job="windows-exporter"}[5m]) - record: node:windows_node_memory_swap_io_pages:irate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (irate(windows_logical_disk_read_seconds_total{job="windows-exporter"}[1m]) + - irate(windows_logical_disk_write_seconds_total{job="windows-exporter"}[1m]) - ) - record: :windows_node_disk_utilisation:avg_irate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( - (irate(windows_logical_disk_read_seconds_total{job="windows-exporter"}[1m]) + - irate(windows_logical_disk_write_seconds_total{job="windows-exporter"}[1m])) - ) - record: node:windows_node_disk_utilisation:avg_irate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,instance,volume)( - (windows_logical_disk_size_bytes{job="windows-exporter"} - - windows_logical_disk_free_bytes{job="windows-exporter"}) - / windows_logical_disk_size_bytes{job="windows-exporter"} - ) - record: 'node:windows_node_filesystem_usage:' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, volume) (windows_logical_disk_free_bytes{job="windows-exporter"} / windows_logical_disk_size_bytes{job="windows-exporter"}) - record: 'node:windows_node_filesystem_avail:' - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (irate(windows_net_bytes_total{job="windows-exporter"}[1m])) - record: :windows_node_net_utilisation:sum_irate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( - (irate(windows_net_bytes_total{job="windows-exporter"}[1m])) - ) - record: node:windows_node_net_utilisation:sum_irate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (irate(windows_net_packets_received_discarded_total{job="windows-exporter"}[1m])) + - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (irate(windows_net_packets_outbound_discarded_total{job="windows-exporter"}[1m])) - record: :windows_node_net_saturation:sum_irate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( - (irate(windows_net_packets_received_discarded_total{job="windows-exporter"}[1m]) + - irate(windows_net_packets_outbound_discarded_total{job="windows-exporter"}[1m])) - ) - record: node:windows_node_net_saturation:sum_irate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/windows.pod.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/windows.pod.rules.yaml deleted file mode 100644 index 86340b5c05..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/rules-1.14/windows.pod.rules.yaml +++ /dev/null @@ -1,158 +0,0 @@ -{{- /* -Generated from 'windows.pod.rules' group from https://github.com/kubernetes-monitoring/kubernetes-mixin.git -Do not change in-place! In order to change this file first read following link: -https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack -*/ -}} -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.windowsMonitoring.enabled .Values.defaultRules.rules.windows }} -{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "windows.pod.rules" | trunc 63 | trimSuffix "-" }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.defaultRules.labels }} -{{ toYaml .Values.defaultRules.labels | indent 4 }} -{{- end }} -{{- if .Values.defaultRules.annotations }} - annotations: -{{ toYaml .Values.defaultRules.annotations | indent 4 }} -{{- end }} -spec: - groups: - - name: windows.pod.rules - rules: - - expr: windows_container_available{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) - record: windows_pod_container_available - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: windows_container_cpu_usage_seconds_total{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) - record: windows_container_total_runtime - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: windows_container_memory_usage_commit_bytes{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) - record: windows_container_memory_usage - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: windows_container_memory_usage_private_working_set_bytes{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) - record: windows_container_private_working_set_usage - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: windows_container_network_receive_bytes_total{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) - record: windows_container_network_received_bytes_total - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: windows_container_network_transmit_bytes_total{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) - record: windows_container_network_transmitted_bytes_total - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, container) ( - kube_pod_container_resource_requests{resource="memory",job="{{ $kubeStateMetricsJob }}"} - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container,pod,namespace,cluster) (windows_pod_container_available) - record: kube_pod_windows_container_resource_memory_request - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: kube_pod_container_resource_limits{resource="memory",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container,pod,namespace,cluster) (windows_pod_container_available) - record: kube_pod_windows_container_resource_memory_limit - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, container) ( - kube_pod_container_resource_requests{resource="cpu",job="{{ $kubeStateMetricsJob }}"} - ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container,pod,namespace,cluster) (windows_pod_container_available) - record: kube_pod_windows_container_resource_cpu_cores_request - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: kube_pod_container_resource_limits{resource="cpu",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container,pod,namespace,cluster) (windows_pod_container_available) - record: kube_pod_windows_container_resource_cpu_cores_limit - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - expr: |- - sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, container) ( - rate(windows_container_total_runtime{}[5m]) - ) - record: namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate - {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} - labels: - {{- with .Values.defaultRules.additionalRuleLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/secret.yaml deleted file mode 100644 index e4a1e73c7b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/secret.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.prometheusSpec.thanos .Values.prometheus.prometheusSpec.thanos.objectStorageConfig}} -{{- if and .Values.prometheus.prometheusSpec.thanos.objectStorageConfig.secret (not .Values.prometheus.prometheusSpec.thanos.objectStorageConfig.existingSecret) }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus - app.kubernetes.io/component: prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: - object-storage-configs.yaml: {{ toYaml .Values.prometheus.prometheusSpec.thanos.objectStorageConfig.secret | b64enc | quote }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/service.yaml deleted file mode 100644 index bfabebe7b9..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/service.yaml +++ /dev/null @@ -1,84 +0,0 @@ -{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} -{{- if .Values.prometheus.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus - self-monitor: {{ .Values.prometheus.serviceMonitor.selfMonitor | quote }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.prometheus.service.labels }} -{{ toYaml .Values.prometheus.service.labels | indent 4 }} -{{- end }} -{{- if .Values.prometheus.service.annotations }} - annotations: -{{ toYaml .Values.prometheus.service.annotations | indent 4 }} -{{- end }} -spec: -{{- if .Values.prometheus.service.clusterIP }} - clusterIP: {{ .Values.prometheus.service.clusterIP }} -{{- end }} -{{- if .Values.prometheus.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.prometheus.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.prometheus.service.ipDualStack.ipFamilyPolicy }} -{{- end }} -{{- if .Values.prometheus.service.externalIPs }} - externalIPs: -{{ toYaml .Values.prometheus.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.prometheus.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.prometheus.service.loadBalancerIP }} -{{- end }} -{{- if .Values.prometheus.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.prometheus.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} -{{- if ne .Values.prometheus.service.type "ClusterIP" }} - externalTrafficPolicy: {{ .Values.prometheus.service.externalTrafficPolicy }} -{{- end }} - ports: - - name: {{ .Values.prometheus.prometheusSpec.portName }} - {{- if eq .Values.prometheus.service.type "NodePort" }} - nodePort: {{ .Values.prometheus.service.nodePort }} - {{- end }} - port: {{ .Values.prometheus.service.port }} - targetPort: {{ .Values.prometheus.service.targetPort }} - - name: reloader-web - {{- if semverCompare "> 1.20.0-0" $kubeTargetVersion }} - appProtocol: http - {{- end }} - port: {{ .Values.prometheus.service.reloaderWebPort }} - targetPort: reloader-web - {{- if .Values.prometheus.thanosIngress.enabled }} - - name: grpc - {{- if eq .Values.prometheus.service.type "NodePort" }} - nodePort: {{ .Values.prometheus.thanosIngress.nodePort }} - {{- end }} - port: {{ .Values.prometheus.thanosIngress.servicePort }} - targetPort: {{ .Values.prometheus.thanosIngress.servicePort }} - {{- end }} -{{- if .Values.prometheus.service.additionalPorts }} -{{ toYaml .Values.prometheus.service.additionalPorts | indent 2 }} -{{- end }} - publishNotReadyAddresses: {{ .Values.prometheus.service.publishNotReadyAddresses }} - selector: - {{- if .Values.prometheus.agentMode }} - app.kubernetes.io/name: prometheus-agent - {{- else }} - app.kubernetes.io/name: prometheus - {{- end }} - operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} -{{- if .Values.prometheus.service.sessionAffinity }} - sessionAffinity: {{ .Values.prometheus.service.sessionAffinity }} -{{- end }} -{{- if eq .Values.prometheus.service.sessionAffinity "ClientIP" }} - sessionAffinityConfig: - clientIP: - timeoutSeconds: {{ .Values.prometheus.service.sessionAffinityConfig.clientIP.timeoutSeconds }} -{{- end }} - type: "{{ .Values.prometheus.service.type }}" -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceThanosSidecar.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceThanosSidecar.yaml deleted file mode 100644 index 87fae7b4f9..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceThanosSidecar.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.thanosService.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-thanos-discovery - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-thanos-discovery -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.prometheus.thanosService.labels }} -{{ toYaml .Values.prometheus.thanosService.labels | indent 4 }} -{{- end }} -{{- if .Values.prometheus.thanosService.annotations }} - annotations: -{{ toYaml .Values.prometheus.thanosService.annotations | indent 4 }} -{{- end }} -spec: - type: {{ .Values.prometheus.thanosService.type }} - clusterIP: {{ .Values.prometheus.thanosService.clusterIP }} -{{- if .Values.prometheus.thanosService.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.prometheus.thanosService.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.prometheus.thanosService.ipDualStack.ipFamilyPolicy }} -{{- end }} -{{- if ne .Values.prometheus.thanosService.type "ClusterIP" }} - externalTrafficPolicy: {{ .Values.prometheus.thanosService.externalTrafficPolicy }} -{{- end }} - ports: - - name: {{ .Values.prometheus.thanosService.portName }} - port: {{ .Values.prometheus.thanosService.port }} - targetPort: {{ .Values.prometheus.thanosService.targetPort }} - {{- if eq .Values.prometheus.thanosService.type "NodePort" }} - nodePort: {{ .Values.prometheus.thanosService.nodePort }} - {{- end }} - - name: {{ .Values.prometheus.thanosService.httpPortName }} - port: {{ .Values.prometheus.thanosService.httpPort }} - targetPort: {{ .Values.prometheus.thanosService.targetHttpPort }} - {{- if eq .Values.prometheus.thanosService.type "NodePort" }} - nodePort: {{ .Values.prometheus.thanosService.httpNodePort }} - {{- end }} - selector: - app.kubernetes.io/name: prometheus - operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceThanosSidecarExternal.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceThanosSidecarExternal.yaml deleted file mode 100644 index 453eed7f1b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceThanosSidecarExternal.yaml +++ /dev/null @@ -1,46 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.thanosServiceExternal.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-thanos-external - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.prometheus.thanosServiceExternal.labels }} -{{ toYaml .Values.prometheus.thanosServiceExternal.labels | indent 4 }} -{{- end }} -{{- if .Values.prometheus.thanosServiceExternal.annotations }} - annotations: -{{ toYaml .Values.prometheus.thanosServiceExternal.annotations | indent 4 }} -{{- end }} -spec: - type: {{ .Values.prometheus.thanosServiceExternal.type }} -{{- if .Values.prometheus.thanosServiceExternal.loadBalancerIP }} - loadBalancerIP: {{ .Values.prometheus.thanosServiceExternal.loadBalancerIP }} -{{- end }} -{{- if .Values.prometheus.thanosServiceExternal.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.prometheus.thanosServiceExternal.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} -{{- if ne .Values.prometheus.thanosServiceExternal.type "ClusterIP" }} - externalTrafficPolicy: {{ .Values.prometheus.thanosServiceExternal.externalTrafficPolicy }} -{{- end }} - ports: - - name: {{ .Values.prometheus.thanosServiceExternal.portName }} - port: {{ .Values.prometheus.thanosServiceExternal.port }} - targetPort: {{ .Values.prometheus.thanosServiceExternal.targetPort }} - {{- if eq .Values.prometheus.thanosServiceExternal.type "NodePort" }} - nodePort: {{ .Values.prometheus.thanosServiceExternal.nodePort }} - {{- end }} - - name: {{ .Values.prometheus.thanosServiceExternal.httpPortName }} - port: {{ .Values.prometheus.thanosServiceExternal.httpPort }} - targetPort: {{ .Values.prometheus.thanosServiceExternal.targetHttpPort }} - {{- if eq .Values.prometheus.thanosServiceExternal.type "NodePort" }} - nodePort: {{ .Values.prometheus.thanosServiceExternal.httpNodePort }} - {{- end }} - selector: - app.kubernetes.io/name: prometheus - operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceaccount.yaml deleted file mode 100644 index e97b989bbd..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceaccount.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.serviceAccount.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "kube-prometheus-stack.prometheus.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus - app.kubernetes.io/name: {{ template "kube-prometheus-stack.name" . }}-prometheus - app.kubernetes.io/component: prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- if .Values.prometheus.serviceAccount.annotations }} - annotations: -{{ toYaml .Values.prometheus.serviceAccount.annotations | indent 4 }} -{{- end }} -automountServiceAccountToken: {{ .Values.prometheus.serviceAccount.automountServiceAccountToken }} -{{- if .Values.global.imagePullSecrets }} -imagePullSecrets: -{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitor.yaml deleted file mode 100644 index a36f3e33ca..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitor.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.serviceMonitor.selfMonitor }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- with .Values.prometheus.serviceMonitor.additionalLabels }} -{{- toYaml . | nindent 4 }} -{{- end }} -spec: - {{- include "servicemonitor.scrapeLimits" .Values.prometheus.serviceMonitor | nindent 2 }} - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-prometheus - release: {{ $.Release.Name | quote }} - self-monitor: "true" - namespaceSelector: - matchNames: - - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} - endpoints: - - port: {{ .Values.prometheus.prometheusSpec.portName }} - {{- if .Values.prometheus.serviceMonitor.interval }} - interval: {{ .Values.prometheus.serviceMonitor.interval }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.scheme }} - scheme: {{ .Values.prometheus.serviceMonitor.scheme }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.tlsConfig }} - tlsConfig: {{- toYaml .Values.prometheus.serviceMonitor.tlsConfig | nindent 6 }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.bearerTokenFile }} - bearerTokenFile: {{ .Values.prometheus.serviceMonitor.bearerTokenFile }} - {{- end }} - path: "{{ trimSuffix "/" .Values.prometheus.prometheusSpec.routePrefix }}/metrics" - metricRelabelings: - {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} - {{- tpl (toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 6) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.relabelings }} - relabelings: {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 6 }} - {{- end }} - - port: reloader-web - {{- if .Values.prometheus.serviceMonitor.interval }} - interval: {{ .Values.prometheus.serviceMonitor.interval }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.scheme }} - scheme: {{ .Values.prometheus.serviceMonitor.scheme }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.tlsConfig }} - tlsConfig: {{- toYaml .Values.prometheus.serviceMonitor.tlsConfig | nindent 6 }} - {{- end }} - path: "/metrics" - {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} - metricRelabelings: {{- tpl (toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 6) . }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.relabelings }} - relabelings: {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 6 }} - {{- end }} - {{- range .Values.prometheus.serviceMonitor.additionalEndpoints }} - - port: {{ .port }} - {{- if or $.Values.prometheus.serviceMonitor.interval .interval }} - interval: {{ default $.Values.prometheus.serviceMonitor.interval .interval }} - {{- end }} - {{- if or $.Values.prometheus.serviceMonitor.proxyUrl .proxyUrl }} - proxyUrl: {{ default $.Values.prometheus.serviceMonitor.proxyUrl .proxyUrl }} - {{- end }} - {{- if or $.Values.prometheus.serviceMonitor.scheme .scheme }} - scheme: {{ default $.Values.prometheus.serviceMonitor.scheme .scheme }} - {{- end }} - {{- if or $.Values.prometheus.serviceMonitor.bearerTokenFile .bearerTokenFile }} - bearerTokenFile: {{ default $.Values.prometheus.serviceMonitor.bearerTokenFile .bearerTokenFile }} - {{- end }} - {{- if or $.Values.prometheus.serviceMonitor.tlsConfig .tlsConfig }} - tlsConfig: {{- default $.Values.prometheus.serviceMonitor.tlsConfig .tlsConfig | toYaml | nindent 6 }} - {{- end }} - path: {{ .path }} - {{- if or $.Values.prometheus.serviceMonitor.metricRelabelings .metricRelabelings }} - metricRelabelings: {{- tpl (default $.Values.prometheus.serviceMonitor.metricRelabelings .metricRelabelings | toYaml | nindent 6) . }} - {{- end }} - {{- if or $.Values.prometheus.serviceMonitor.relabelings .relabelings }} - relabelings: {{- default $.Values.prometheus.serviceMonitor.relabelings .relabelings | toYaml | nindent 6 }} - {{- end }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitorThanosSidecar.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitorThanosSidecar.yaml deleted file mode 100644 index 0f70aabb58..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitorThanosSidecar.yaml +++ /dev/null @@ -1,55 +0,0 @@ -{{- if and .Values.prometheus.thanosService.enabled .Values.prometheus.thanosServiceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-thanos-sidecar - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-thanos-sidecar -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- with .Values.prometheus.thanosServiceMonitor.additionalLabels }} -{{- toYaml . | nindent 4 }} -{{- end }} -spec: - {{- include "servicemonitor.scrapeLimits" .Values.prometheus.thanosServiceMonitor | nindent 2 }} - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-thanos-discovery - release: {{ $.Release.Name | quote }} - namespaceSelector: - matchNames: - - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} - endpoints: - - port: {{ .Values.prometheus.thanosService.httpPortName }} - {{- if .Values.prometheus.thanosServiceMonitor.interval }} - interval: {{ .Values.prometheus.thanosServiceMonitor.interval }} - {{- end }} - {{- if .Values.prometheus.thanosServiceMonitor.scheme }} - scheme: {{ .Values.prometheus.thanosServiceMonitor.scheme }} - {{- end }} - {{- if .Values.prometheus.thanosServiceMonitor.tlsConfig }} - tlsConfig: {{ toYaml .Values.prometheus.thanosServiceMonitor.tlsConfig | nindent 6 }} - {{- end }} - {{- if .Values.prometheus.thanosServiceMonitor.bearerTokenFile }} - bearerTokenFile: {{ .Values.prometheus.thanosServiceMonitor.bearerTokenFile }} - {{- end }} - path: "/metrics" - metricRelabelings: - {{- if .Values.prometheus.thanosServiceMonitor.metricRelabelings}} - {{ tpl (toYaml .Values.prometheus.thanosServiceMonitor.metricRelabelings | indent 6) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.prometheus.thanosServiceMonitor.relabelings }} - relabelings: -{{ toYaml .Values.prometheus.thanosServiceMonitor.relabelings | indent 6 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitors.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitors.yaml deleted file mode 100644 index a7a301babc..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/servicemonitors.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.additionalServiceMonitors }} -apiVersion: v1 -kind: List -items: -{{- range .Values.prometheus.additionalServiceMonitors }} - - apiVersion: monitoring.coreos.com/v1 - kind: ServiceMonitor - metadata: - name: {{ .name }} - namespace: {{ template "kube-prometheus-stack.namespace" $ }} - labels: - app: {{ template "kube-prometheus-stack.name" $ }}-prometheus -{{ include "kube-prometheus-stack.labels" $ | indent 8 }} - {{- if .additionalLabels }} -{{ toYaml .additionalLabels | indent 8 }} - {{- end }} - spec: - {{- include "servicemonitor.scrapeLimits" . | nindent 6 }} - endpoints: -{{ toYaml .endpoints | indent 8 }} - {{- if .jobLabel }} - jobLabel: {{ .jobLabel }} - {{- end }} - {{- if .namespaceSelector }} - namespaceSelector: -{{ toYaml .namespaceSelector | indent 8 }} - {{- end }} - selector: -{{ toYaml .selector | indent 8 }} - {{- if .targetLabels }} - targetLabels: -{{ toYaml .targetLabels | indent 8 }} - {{- end }} - {{- if .podTargetLabels }} - podTargetLabels: -{{ toYaml .podTargetLabels | indent 8 }} - {{- end }} - {{- if .metricRelabelings }} - metricRelabelings: -{{ toYaml .metricRelabelings | indent 8 }} - {{- end }} - {{- if .relabelings }} - relabelings: -{{ toYaml .relabelings | indent 8 }} - {{- end }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceperreplica.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceperreplica.yaml deleted file mode 100644 index 3a88b2df34..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/prometheus/serviceperreplica.yaml +++ /dev/null @@ -1,58 +0,0 @@ -{{- if and .Values.prometheus.enabled .Values.prometheus.servicePerReplica.enabled }} -{{- $count := .Values.prometheus.prometheusSpec.replicas | int -}} -{{- $serviceValues := .Values.prometheus.servicePerReplica -}} -apiVersion: v1 -kind: List -metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-serviceperreplica - namespace: {{ template "kube-prometheus-stack.namespace" . }} -items: -{{- range $i, $e := until $count }} - - apiVersion: v1 - kind: Service - metadata: - name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-{{ $i }} - namespace: {{ template "kube-prometheus-stack.namespace" $ }} - labels: - app: {{ include "kube-prometheus-stack.name" $ }}-prometheus -{{ include "kube-prometheus-stack.labels" $ | indent 8 }} - {{- if $serviceValues.annotations }} - annotations: -{{ toYaml $serviceValues.annotations | indent 8 }} - {{- end }} - spec: - {{- if $serviceValues.clusterIP }} - clusterIP: {{ $serviceValues.clusterIP }} - {{- end }} - {{- if $serviceValues.ipDualStack.enabled }} - ipFamilies: {{ toYaml $serviceValues.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ $serviceValues.ipDualStack.ipFamilyPolicy }} - {{- end }} - {{- if $serviceValues.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := $serviceValues.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} - {{- end }} - {{- if ne $serviceValues.type "ClusterIP" }} - externalTrafficPolicy: {{ $serviceValues.externalTrafficPolicy }} - {{- end }} - ports: - - name: {{ $.Values.prometheus.prometheusSpec.portName }} - {{- if eq $serviceValues.type "NodePort" }} - nodePort: {{ $serviceValues.nodePort }} - {{- end }} - port: {{ $serviceValues.port }} - targetPort: {{ $serviceValues.targetPort }} - selector: - {{- if $.Values.prometheus.agentMode }} - app.kubernetes.io/name: prometheus-agent - statefulset.kubernetes.io/pod-name: prom-agent-{{ include "kube-prometheus-stack.prometheus.crname" $ }}-{{ $i }} - {{- else }} - app.kubernetes.io/name: prometheus - statefulset.kubernetes.io/pod-name: prometheus-{{ include "kube-prometheus-stack.prometheus.crname" $ }}-{{ $i }} - {{- end }} - operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" $ }} - type: "{{ $serviceValues.type }}" -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/clusterrole.yaml deleted file mode 100644 index 56ca9f5eae..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/clusterrole.yaml +++ /dev/null @@ -1,135 +0,0 @@ -{{- if and .Values.global.rbac.create .Values.global.rbac.userRoles.create }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: monitoring-admin - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} - {{- if .Values.global.rbac.userRoles.aggregateToDefaultRoles }} - rbac.authorization.k8s.io/aggregate-to-admin: "true" - {{- end }} -rules: -- apiGroups: - - monitoring.coreos.com - resources: - - alertmanagers - - prometheuses - - prometheuses/finalizers - - alertmanagers/finalizers - verbs: - - 'get' - - 'list' - - 'watch' -- apiGroups: - - monitoring.coreos.com - resources: - - thanosrulers - - thanosrulers/finalizers - - servicemonitors - - podmonitors - - prometheusrules - - podmonitors - - probes - - probes/finalizers - - alertmanagerconfigs - verbs: - - '*' ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: monitoring-edit - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} - {{- if .Values.global.rbac.userRoles.aggregateToDefaultRoles }} - rbac.authorization.k8s.io/aggregate-to-edit: "true" - {{- end }} -rules: -- apiGroups: - - monitoring.coreos.com - resources: - - alertmanagers - - prometheuses - - prometheuses/finalizers - - alertmanagers/finalizers - verbs: - - 'get' - - 'list' - - 'watch' -- apiGroups: - - monitoring.coreos.com - resources: - - thanosrulers - - thanosrulers/finalizers - - servicemonitors - - podmonitors - - prometheusrules - - podmonitors - - probes - - alertmanagerconfigs - verbs: - - '*' ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: monitoring-view - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} - {{- if .Values.global.rbac.userRoles.aggregateToDefaultRoles }} - rbac.authorization.k8s.io/aggregate-to-view: "true" - {{- end }} -rules: -- apiGroups: - - monitoring.coreos.com - resources: - - alertmanagers - - prometheuses - - prometheuses/finalizers - - alertmanagers/finalizers - - thanosrulers - - thanosrulers/finalizers - - servicemonitors - - podmonitors - - prometheusrules - - podmonitors - - probes - - probes/finalizers - - alertmanagerconfigs - verbs: - - 'get' - - 'list' - - 'watch' ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: monitoring-ui-view - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} -rules: -- apiGroups: - - "" - resources: - - services/proxy - resourceNames: - - "http:{{ template "kube-prometheus-stack.fullname" . }}-prometheus:{{ .Values.prometheus.service.port }}" - - "https:{{ template "kube-prometheus-stack.fullname" . }}-prometheus:{{ .Values.prometheus.service.port }}" - - "http:{{ template "kube-prometheus-stack.fullname" . }}-alertmanager:{{ .Values.alertmanager.service.port }}" - - "https:{{ template "kube-prometheus-stack.fullname" . }}-alertmanager:{{ .Values.alertmanager.service.port }}" -{{- if .Values.grafana.enabled }} - - "http:{{ include "call-nested" (list . "grafana" "grafana.fullname") }}:{{ .Values.grafana.service.port }}" - - "https:{{ include "call-nested" (list . "grafana" "grafana.fullname") }}:{{ .Values.grafana.service.port }}" -{{- end }} - verbs: - - 'get' - - 'create' -- apiGroups: - - "" - resourceNames: - - {{ template "kube-prometheus-stack.fullname" . }}-prometheus - - {{ template "kube-prometheus-stack.fullname" . }}-alertmanager -{{- if .Values.grafana.enabled }} - - {{ include "call-nested" (list . "grafana" "grafana.fullname") }} -{{- end }} - resources: - - endpoints - verbs: - - list -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/config-role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/config-role.yaml deleted file mode 100644 index f48ffc827e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/config-role.yaml +++ /dev/null @@ -1,48 +0,0 @@ -{{- if and .Values.global.rbac.create .Values.global.rbac.userRoles.create }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: monitoring-config-admin - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} -rules: -- apiGroups: - - "" - resources: - - configmaps - - secrets - verbs: - - '*' ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: monitoring-config-edit - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} -rules: -- apiGroups: - - "" - resources: - - configmaps - - secrets - verbs: - - '*' ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: monitoring-config-view - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} -rules: -- apiGroups: - - "" - resources: - - configmaps - - secrets - verbs: - - 'get' - - 'list' - - 'watch' -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboard-role.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboard-role.yaml deleted file mode 100644 index d2f81976a2..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboard-role.yaml +++ /dev/null @@ -1,47 +0,0 @@ -{{- if and .Values.global.rbac.create .Values.global.rbac.userRoles.create .Values.grafana.enabled }} -{{- if .Values.grafana.defaultDashboardsEnabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: monitoring-dashboard-admin - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - '*' ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: monitoring-dashboard-edit - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - '*' ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: monitoring-dashboard-view - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - 'get' - - 'list' - - 'watch' -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml deleted file mode 100644 index 7b51a0bf7a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled .Values.ingressNginx.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "ingress-nginx" | trunc 63 | trimSuffix "-" }} - {{- if .Values.grafana.sidecar.dashboards.annotations }} - annotations: {{ toYaml .Values.grafana.sidecar.dashboards.annotations | nindent 4 }} - {{- end }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/ingress-nginx/*").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml deleted file mode 100644 index d73b257451..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-default-dashboards-cluster - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/cluster/*").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml deleted file mode 100644 index 8865efa932..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-default-dashboards-home - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/home/*").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml deleted file mode 100644 index 9b05cea2e8..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-fleet-dashboards - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/fleet/*").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentbit-dashboard.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentbit-dashboard.yaml deleted file mode 100644 index b2d1bfcb73..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentbit-dashboard.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled .Values.loggingMonitors.fluentbit.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-fluentbit-dashboard - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/logging/fluentbit.json").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentd-dashboard.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentd-dashboard.yaml deleted file mode 100644 index 66c9cb845a..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentd-dashboard.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled .Values.loggingMonitors.fluentd.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-fluentd-dashboard - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/logging/fluentd.json").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml deleted file mode 100644 index 2afae10ef7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml +++ /dev/null @@ -1,31 +0,0 @@ -{{- $files := (.Files.Glob "files/rancher/k8s/*").AsConfig }} -{{- $filesDict := (fromYaml $files) }} -{{- if not (include "exporter.kubeEtcd.enabled" .) }} -{{- $filesDict = (unset $filesDict "rancher-etcd-nodes.json") -}} -{{- $filesDict = (unset $filesDict "rancher-etcd.json") -}} -{{- end }} -{{- if not (include "exporter.kubeControllerManager.enabled" .) }} -{{- $filesDict = (unset $filesDict "rancher-k8s-components-nodes.json") -}} -{{- $filesDict = (unset $filesDict "rancher-k8s-components.json") -}} -{{- else }} -{{- $_ := (set $filesDict "rancher-k8s-components-nodes.json" (get $filesDict "rancher-k8s-components-nodes.json" | replace "kube-controller-manager" (include "exporter.kubeControllerManager.jobName" .))) -}} -{{- $_ := (set $filesDict "rancher-k8s-components.json" (get $filesDict "rancher-k8s-components.json" | replace "kube-controller-manager" (include "exporter.kubeControllerManager.jobName" .))) -}} -{{- end }} -{{ $files = (toYaml $filesDict) }} -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-default-dashboards-k8s - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ $files | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml deleted file mode 100644 index 172c36e9d1..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-default-dashboards-nodes - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/nodes/*").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml deleted file mode 100644 index 19836ec4e4..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- $selector := (include "rancher.serviceMonitor.selector" .) -}} -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled .Values.rancherMonitoring.enabled $selector }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-default-dashboards-performance-debugging - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/performance/*").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml deleted file mode 100644 index 940f18869b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-default-dashboards-pods - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/pods/*").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml deleted file mode 100644 index d146dacdd0..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: {{ .Values.grafana.defaultDashboards.namespace }} - name: rancher-default-dashboards-workloads - annotations: -{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} - labels: - {{- if $.Values.grafana.sidecar.dashboards.label }} - {{ $.Values.grafana.sidecar.dashboards.label }}: "1" - {{- end }} - app: {{ template "kube-prometheus-stack.name" $ }}-grafana -{{ include "kube-prometheus-stack.labels" $ | indent 4 }} -data: -{{ (.Files.Glob "files/rancher/workloads/*").AsConfig | indent 2 }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml deleted file mode 100644 index 90d24c2061..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml +++ /dev/null @@ -1,53 +0,0 @@ -{{- if .Values.rancherMonitoring.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} - name: monitoring-fleet-controller - namespace: cattle-fleet-system -spec: - endpoints: - - port: metrics - metricRelabelings: - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} - jobLabel: fleet - selector: - matchLabels: - app: fleet-controller -{{- end }} ---- -{{- if .Values.rancherMonitoring.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} - name: monitoring-gitops-controller - namespace: cattle-fleet-system -spec: - endpoints: - - port: metrics - metricRelabelings: - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} - jobLabel: gitops - selector: - matchLabels: - app: gitjob -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml deleted file mode 100644 index 53a9ad6897..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml +++ /dev/null @@ -1,27 +0,0 @@ -{{- if and (not .Values.ingressNginx.enabled) (.Values.rkeIngressNginx.enabled) }} -{{- fail "Cannot set .Values.rkeIngressNginx.enabled=true when .Values.ingressNginx.enabled=false" }} -{{- end }} -{{- if and .Values.ingressNginx.enabled (not .Values.rkeIngressNginx.enabled) }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-ingress-nginx - labels: - app: {{ template "kube-prometheus-stack.name" . }}-ingress-nginx - jobLabel: ingress-nginx -{{ include "kube-prometheus-stack.labels" . | indent 4 }} - namespace: {{ .Values.ingressNginx.namespace }} -spec: - clusterIP: None - ports: - - name: http-metrics - port: {{ .Values.ingressNginx.service.port }} - protocol: TCP - targetPort: {{ .Values.ingressNginx.service.targetPort }} - selector: - {{- if .Values.ingressNginx.service.selector }} -{{ toYaml .Values.ingressNginx.service.selector | indent 4 }} - {{- else }} - app: ingress-nginx - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml deleted file mode 100644 index b0f92e63b5..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml +++ /dev/null @@ -1,49 +0,0 @@ -{{- if and (not .Values.ingressNginx.enabled) (.Values.rkeIngressNginx.enabled) }} -{{- fail "Cannot set .Values.rkeIngressNginx.enabled=true when .Values.ingressNginx.enabled=false" }} -{{- end }} -{{- if and .Values.ingressNginx.enabled (not .Values.rkeIngressNginx.enabled) }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-ingress-nginx - namespace: {{ .Values.ingressNginx.namespace }} - labels: - app: {{ template "kube-prometheus-stack.name" . }}-ingress-nginx -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - jobLabel: jobLabel - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.name" . }}-ingress-nginx - release: {{ $.Release.Name | quote }} - namespaceSelector: - matchNames: - - {{ .Values.ingressNginx.namespace }} - endpoints: - - port: http-metrics - {{- if .Values.ingressNginx.serviceMonitor.interval}} - interval: {{ .Values.ingressNginx.serviceMonitor.interval }} - {{- end }} - {{- if .Values.ingressNginx.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.ingressNginx.serviceMonitor.proxyUrl}} - {{- end }} - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - metricRelabelings: - {{- if .Values.ingressNginx.serviceMonitor.metricRelabelings }} - {{ tpl (toYaml .Values.ingressNginx.serviceMonitor.metricRelabelings | indent 4) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} -{{- if .Values.ingressNginx.serviceMonitor.relabelings }} - relabelings: -{{ toYaml .Values.ingressNginx.serviceMonitor.relabelings | indent 4 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml deleted file mode 100644 index 1fba8f23f7..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml +++ /dev/null @@ -1,58 +0,0 @@ -{{- $selector := (include "rancher.serviceMonitor.selector" .) -}} -{{- if and .Values.rancherMonitoring.enabled $selector }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} - name: rancher - namespace: cattle-system -spec: - endpoints: - - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - port: http - tlsConfig: - caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - insecureSkipVerify: true - serverName: rancher - metricRelabelings: - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} - jobLabel: rancher -{{- if .Values.rancherMonitoring.namespaceSelector }} - namespaceSelector: {{ .Values.rancherMonitoring.namespaceSelector | toYaml | nindent 4 }} -{{- end }} - selector: {{ include "rancher.serviceMonitor.selector" . | nindent 4 }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-rancher-metrics -rules: -- apiGroups: - - management.cattle.io - resources: - - ranchermetrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-rancher-metrics -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "kube-prometheus-stack.fullname" . }}-rancher-metrics -subjects: - - kind: ServiceAccount - name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/hardened.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/hardened.yaml deleted file mode 100644 index 63bac7fd42..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/hardened.yaml +++ /dev/null @@ -1,91 +0,0 @@ -{{- $namespaces := dict "_0" .Release.Namespace -}} -{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled (not .Values.grafana.defaultDashboards.useExistingNamespace) -}} -{{- $_ := set $namespaces "_1" .Values.grafana.defaultDashboards.namespace -}} -{{- end -}} -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ .Chart.Name }}-patch-sa - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Chart.Name }}-patch-sa - annotations: - "helm.sh/hook": post-install, post-upgrade - "helm.sh/hook-delete-policy": hook-succeeded, before-hook-creation -spec: - template: - metadata: - name: {{ .Chart.Name }}-patch-sa - labels: - app: {{ .Chart.Name }}-patch-sa - spec: - serviceAccountName: {{ .Chart.Name }}-patch-sa - securityContext: - runAsNonRoot: true - runAsUser: 1000 - restartPolicy: Never - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} - containers: - {{- range $_, $ns := $namespaces }} - - name: patch-sa-{{ $ns }} - image: {{ template "system_default_registry" $ }}{{ $.Values.global.kubectl.repository }}:{{ $.Values.global.kubectl.tag }} - imagePullPolicy: {{ $.Values.global.kubectl.pullPolicy }} - command: ["kubectl", "patch", "serviceaccount", "default", "-p", "{\"automountServiceAccountToken\": false}"] - args: ["-n", "{{ $ns }}"] - {{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ .Chart.Name }}-patch-sa - labels: - app: {{ .Chart.Name }}-patch-sa -rules: -- apiGroups: - - "" - resources: - - serviceaccounts - verbs: ['get', 'patch'] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ .Chart.Name }}-patch-sa - labels: - app: {{ .Chart.Name }}-patch-sa -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ .Chart.Name }}-patch-sa -subjects: -- kind: ServiceAccount - name: {{ .Chart.Name }}-patch-sa - namespace: {{ .Release.Namespace }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Chart.Name }}-patch-sa - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Chart.Name }}-patch-sa ---- -{{- if .Values.hardened.k3s.networkPolicy.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: rancher-monitoring-coredns-allow-all - namespace: kube-system -spec: - ingress: - - {} - egress: - - {} - policyTypes: - - Ingress - - Egress - podSelector: - matchLabels: - k8s-app: kube-dns -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/configmap.yaml deleted file mode 100644 index 53cb898214..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/configmap.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if .Values.upgrade.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - namespace: {{ template "kube-prometheus-stack.namespace" . }} - annotations: - "helm.sh/hook": pre-upgrade, pre-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "0" -data: -{{ (.Files.Glob "files/upgrade/scripts/*").AsConfig | indent 2 }} -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/job.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/job.yaml deleted file mode 100644 index 8f2771740c..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/job.yaml +++ /dev/null @@ -1,46 +0,0 @@ -{{- if .Values.upgrade.enabled }} -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - annotations: - "helm.sh/hook": pre-upgrade, pre-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "2" -spec: - template: - metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - labels: - app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - spec: - serviceAccountName: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - securityContext: - runAsNonRoot: false - runAsUser: 0 - restartPolicy: Never - nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} - tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} - containers: - - name: run-scripts - image: {{ template "system_default_registry" . }}{{ .Values.upgrade.image.repository }}:{{ .Values.upgrade.image.tag }} - imagePullPolicy: {{ $.Values.global.kubectl.pullPolicy }} - command: - - /bin/sh - - -c - - > - for s in $(find /etc/scripts -type f); do - echo "Running $s..."; - cat $s | bash - done; - volumeMounts: - - name: upgrade - mountPath: /etc/scripts - volumes: - - name: upgrade - configMap: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/rbac.yaml deleted file mode 100644 index 46bdd3a36b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/rancher-monitoring/upgrade/rbac.yaml +++ /dev/null @@ -1,86 +0,0 @@ -{{- if .Values.upgrade.enabled }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - annotations: - "helm.sh/hook": pre-upgrade, pre-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded - "helm.sh/hook-weight": "1" -rules: -- apiGroups: - - apps - resources: - - deployments - - daemonsets - - statefulsets - verbs: - - 'list' - - 'delete' ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - annotations: - "helm.sh/hook": pre-upgrade, pre-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "1" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade -subjects: -- kind: ServiceAccount - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - namespace: {{ template "kube-prometheus-stack.namespace" . }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - labels: - app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - annotations: - "helm.sh/hook": pre-upgrade, pre-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "1" -rules: ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - labels: - app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - annotations: - "helm.sh/hook": pre-upgrade, pre-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "1" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade -subjects: -- kind: ServiceAccount - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - namespace: {{ template "kube-prometheus-stack.namespace" . }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade - annotations: - "helm.sh/hook": pre-upgrade, pre-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "1" -{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/extrasecret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/extrasecret.yaml deleted file mode 100644 index 587fca2dca..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/extrasecret.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.thanosRuler.extraSecret.data -}} -{{- $secretName := printf "%s-extra" (include "kube-prometheus-stack.thanosRuler.name" . ) -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ default $secretName .Values.thanosRuler.extraSecret.name }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- if .Values.thanosRuler.extraSecret.annotations }} - annotations: -{{ toYaml .Values.thanosRuler.extraSecret.annotations | indent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - app.kubernetes.io/component: thanos-ruler -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: -{{- range $key, $val := .Values.thanosRuler.extraSecret.data }} - {{ $key }}: {{ $val | b64enc | quote }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/ingress.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/ingress.yaml deleted file mode 100644 index e245ad448e..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/ingress.yaml +++ /dev/null @@ -1,77 +0,0 @@ -{{- if and .Values.thanosRuler.enabled .Values.thanosRuler.ingress.enabled }} -{{- $pathType := .Values.thanosRuler.ingress.pathType | default "ImplementationSpecific" }} -{{- $serviceName := include "kube-prometheus-stack.thanosRuler.name" . }} -{{- $servicePort := .Values.thanosRuler.service.port -}} -{{- $routePrefix := list .Values.thanosRuler.thanosRulerSpec.routePrefix }} -{{- $paths := .Values.thanosRuler.ingress.paths | default $routePrefix -}} -{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} -{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} -apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" . }} -kind: Ingress -metadata: - name: {{ $serviceName }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} -{{- if .Values.thanosRuler.ingress.annotations }} - annotations: - {{- tpl (toYaml .Values.thanosRuler.ingress.annotations) . | nindent 4 }} -{{- end }} - labels: - app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} -{{- if .Values.thanosRuler.ingress.labels }} -{{ toYaml .Values.thanosRuler.ingress.labels | indent 4 }} -{{- end }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - {{- if $apiIsStable }} - {{- if .Values.thanosRuler.ingress.ingressClassName }} - ingressClassName: {{ .Values.thanosRuler.ingress.ingressClassName }} - {{- end }} - {{- end }} - rules: - {{- if .Values.thanosRuler.ingress.hosts }} - {{- range $host := .Values.thanosRuler.ingress.hosts }} - - host: {{ tpl $host $ }} - http: - paths: - {{- range $p := $paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ $serviceName }} - port: - number: {{ $servicePort }} - {{- else }} - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end }} - {{- end -}} - {{- end -}} - {{- else }} - - http: - paths: - {{- range $p := $paths }} - - path: {{ tpl $p $ }} - {{- if and $pathType $ingressSupportsPathType }} - pathType: {{ $pathType }} - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ $serviceName }} - port: - number: {{ $servicePort }} - {{- else }} - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end }} - {{- end -}} - {{- end -}} - {{- if .Values.thanosRuler.ingress.tls }} - tls: -{{ tpl (toYaml .Values.thanosRuler.ingress.tls | indent 4) . }} - {{- end -}} -{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/podDisruptionBudget.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/podDisruptionBudget.yaml deleted file mode 100644 index c28f914647..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/podDisruptionBudget.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.thanosRuler.enabled .Values.thanosRuler.podDisruptionBudget.enabled }} -apiVersion: {{ include "kube-prometheus-stack.pdb.apiVersion" . }} -kind: PodDisruptionBudget -metadata: - name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -spec: - {{- if .Values.thanosRuler.podDisruptionBudget.minAvailable }} - minAvailable: {{ .Values.thanosRuler.podDisruptionBudget.minAvailable }} - {{- end }} - {{- if .Values.thanosRuler.podDisruptionBudget.maxUnavailable }} - maxUnavailable: {{ .Values.thanosRuler.podDisruptionBudget.maxUnavailable }} - {{- end }} - selector: - matchLabels: - app.kubernetes.io/name: thanos-ruler - thanos-ruler: {{ template "kube-prometheus-stack.thanosRuler.crname" . }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/ruler.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/ruler.yaml deleted file mode 100644 index 94dc60be3f..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/ruler.yaml +++ /dev/null @@ -1,200 +0,0 @@ -{{- if .Values.thanosRuler.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ThanosRuler -metadata: - name: {{ template "kube-prometheus-stack.thanosRuler.crname" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ include "kube-prometheus-stack.thanosRuler.name" . }} -{{- include "kube-prometheus-stack.labels" . | indent 4 -}} -{{- if .Values.thanosRuler.annotations }} - annotations: -{{ toYaml .Values.thanosRuler.annotations | indent 4 }} -{{- end }} -spec: -{{- if .Values.thanosRuler.thanosRulerSpec.image }} - {{- $registry := include "monitoring_registry" . | default .Values.thanosRuler.thanosRulerSpec.image.registry -}} - {{- if and .Values.thanosRuler.thanosRulerSpec.image.tag .Values.thanosRuler.thanosRulerSpec.image.sha }} - image: "{{ $registry }}/{{ .Values.thanosRuler.thanosRulerSpec.image.repository }}:{{ .Values.thanosRuler.thanosRulerSpec.image.tag }}@sha256:{{ .Values.thanosRuler.thanosRulerSpec.image.sha }}" - {{- else if .Values.thanosRuler.thanosRulerSpec.image.sha }} - image: "{{ $registry }}/{{ .Values.thanosRuler.thanosRulerSpec.image.repository }}@sha256:{{ .Values.thanosRuler.thanosRulerSpec.image.sha }}" - {{- else if .Values.thanosRuler.thanosRulerSpec.image.tag }} - image: "{{ $registry }}/{{ .Values.thanosRuler.thanosRulerSpec.image.repository }}:{{ .Values.thanosRuler.thanosRulerSpec.image.tag }}" - {{- else }} - image: "{{ $registry }}/{{ .Values.thanosRuler.thanosRulerSpec.image.repository }}" - {{- end }} - {{- if .Values.thanosRuler.thanosRulerSpec.image.sha }} - sha: {{ .Values.thanosRuler.thanosRulerSpec.image.sha }} - {{- end }} -{{- end }} - replicas: {{ .Values.thanosRuler.thanosRulerSpec.replicas }} - listenLocal: {{ .Values.thanosRuler.thanosRulerSpec.listenLocal }} - serviceAccountName: {{ template "kube-prometheus-stack.thanosRuler.serviceAccountName" . }} -{{- if .Values.thanosRuler.thanosRulerSpec.externalPrefix }} - externalPrefix: "{{ tpl .Values.thanosRuler.thanosRulerSpec.externalPrefix . }}" -{{- else if and .Values.thanosRuler.ingress.enabled .Values.thanosRuler.ingress.hosts }} - externalPrefix: "http://{{ tpl (index .Values.thanosRuler.ingress.hosts 0) . }}{{ .Values.thanosRuler.thanosRulerSpec.routePrefix }}" -{{- else if .Values.thanosRuler.thanosRulerSpec.externalPrefixNilUsesHelmValues }} - externalPrefix: "http://{{ template "kube-prometheus-stack.thanosRuler.name" . }}.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.thanosRuler.service.port }}" -{{- end }} - nodeSelector: {{ include "linux-node-selector" . | nindent 4 }} -{{- if .Values.thanosRuler.thanosRulerSpec.additionalArgs }} - additionalArgs: -{{ tpl (toYaml .Values.thanosRuler.thanosRulerSpec.additionalArgs) $ | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.nodeSelector }} - nodeSelector: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.nodeSelector | indent 4 }} -{{- end }} - paused: {{ .Values.thanosRuler.thanosRulerSpec.paused }} - logFormat: {{ .Values.thanosRuler.thanosRulerSpec.logFormat | quote }} - logLevel: {{ .Values.thanosRuler.thanosRulerSpec.logLevel | quote }} - retention: {{ .Values.thanosRuler.thanosRulerSpec.retention | quote }} -{{- if .Values.thanosRuler.thanosRulerSpec.evaluationInterval }} - evaluationInterval: {{ .Values.thanosRuler.thanosRulerSpec.evaluationInterval }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.ruleNamespaceSelector }} - ruleNamespaceSelector: -{{ tpl (toYaml .Values.thanosRuler.thanosRulerSpec.ruleNamespaceSelector | indent 4) . }} -{{ else }} - ruleNamespaceSelector: {} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.ruleSelector }} - ruleSelector: -{{ tpl (toYaml .Values.thanosRuler.thanosRulerSpec.ruleSelector | indent 4) .}} -{{- else if .Values.thanosRuler.thanosRulerSpec.ruleSelectorNilUsesHelmValues }} - ruleSelector: - matchLabels: - release: {{ $.Release.Name | quote }} -{{ else }} - ruleSelector: {} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.alertQueryUrl }} - alertQueryUrl: "{{ .Values.thanosRuler.thanosRulerSpec.alertQueryUrl }}" -{{- end}} -{{- if .Values.thanosRuler.thanosRulerSpec.alertmanagersUrl }} - alertmanagersUrl: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.alertmanagersUrl | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.alertmanagersConfig.existingSecret }} - alertmanagersConfig: - key: "{{.Values.thanosRuler.thanosRulerSpec.alertmanagersConfig.existingSecret.key }}" - name: "{{.Values.thanosRuler.thanosRulerSpec.alertmanagersConfig.existingSecret.name }}" -{{- else if .Values.thanosRuler.thanosRulerSpec.alertmanagersConfig.secret }} - alertmanagersConfig: - key: alertmanager-configs.yaml - name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.queryEndpoints }} - queryEndpoints: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.queryEndpoints | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.queryConfig.existingSecret }} - queryConfig: - key: "{{.Values.thanosRuler.thanosRulerSpec.queryConfig.existingSecret.key }}" - name: "{{.Values.thanosRuler.thanosRulerSpec.queryConfig.existingSecret.name }}" -{{- else if .Values.thanosRuler.thanosRulerSpec.queryConfig.secret }} - queryConfig: - key: query-configs.yaml - name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.resources }} - resources: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.resources | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.routePrefix }} - routePrefix: "{{ .Values.thanosRuler.thanosRulerSpec.routePrefix }}" -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.securityContext }} - securityContext: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.securityContext | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.storage }} - storage: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.storage | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.objectStorageConfig.existingSecret }} - objectStorageConfig: - key: "{{.Values.thanosRuler.thanosRulerSpec.objectStorageConfig.existingSecret.key }}" - name: "{{.Values.thanosRuler.thanosRulerSpec.objectStorageConfig.existingSecret.name }}" -{{- else if .Values.thanosRuler.thanosRulerSpec.objectStorageConfig.secret }} - objectStorageConfig: - key: object-storage-configs.yaml - name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.labels }} - labels: -{{ tpl (toYaml .Values.thanosRuler.thanosRulerSpec.labels) $ | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.podMetadata }} - podMetadata: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.podMetadata | indent 4 }} -{{- end }} -{{- if or .Values.thanosRuler.thanosRulerSpec.podAntiAffinity .Values.thanosRuler.thanosRulerSpec.affinity }} - affinity: -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.affinity }} -{{ toYaml .Values.thanosRuler.thanosRulerSpec.affinity | indent 4 }} -{{- end }} -{{- if eq .Values.thanosRuler.thanosRulerSpec.podAntiAffinity "hard" }} - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - topologyKey: {{ .Values.thanosRuler.thanosRulerSpec.podAntiAffinityTopologyKey }} - labelSelector: - matchExpressions: - - {key: app.kubernetes.io/name, operator: In, values: [thanos-ruler]} - - {key: thanos-ruler, operator: In, values: [{{ template "kube-prometheus-stack.thanosRuler.crname" . }}]} -{{- else if eq .Values.thanosRuler.thanosRulerSpec.podAntiAffinity "soft" }} - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - topologyKey: {{ .Values.thanosRuler.thanosRulerSpec.podAntiAffinityTopologyKey }} - labelSelector: - matchExpressions: - - {key: app.kubernetes.io/name, operator: In, values: [thanos-ruler]} - - {key: thanos-ruler, operator: In, values: [{{ template "kube-prometheus-stack.thanosRuler.crname" . }}]} -{{- end }} - tolerations: {{ include "linux-node-tolerations" . | nindent 4 }} -{{- if .Values.thanosRuler.thanosRulerSpec.tolerations }} -{{ toYaml .Values.thanosRuler.thanosRulerSpec.tolerations | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.topologySpreadConstraints }} - topologySpreadConstraints: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.topologySpreadConstraints | indent 4 }} -{{- end }} -{{- if .Values.global.imagePullSecrets }} - imagePullSecrets: -{{ toYaml .Values.global.imagePullSecrets | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.containers }} - containers: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.containers | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.initContainers }} - initContainers: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.initContainers | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.priorityClassName }} - priorityClassName: {{.Values.thanosRuler.thanosRulerSpec.priorityClassName }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.volumes }} - volumes: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.volumes | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.volumeMounts }} - volumeMounts: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.volumeMounts | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.thanosRulerSpec.alertDropLabels }} - alertDropLabels: -{{ toYaml .Values.thanosRuler.thanosRulerSpec.alertDropLabels | indent 4 }} -{{- end }} - portName: {{ .Values.thanosRuler.thanosRulerSpec.portName }} -{{- with .Values.thanosRuler.thanosRulerSpec.additionalConfig }} - {{- tpl (toYaml .) $ | nindent 2 }} -{{- end }} -{{- with .Values.thanosRuler.thanosRulerSpec.additionalConfigString }} - {{- tpl . $ | nindent 2 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/secret.yaml deleted file mode 100644 index acab7fd9ae..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/secret.yaml +++ /dev/null @@ -1,26 +0,0 @@ -{{- if .Values.thanosRuler.enabled }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ include "kube-prometheus-stack.thanosRuler.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -data: - {{- with .Values.thanosRuler.thanosRulerSpec.alertmanagersConfig }} - {{- if and .secret (not .existingSecret) }} - alertmanager-configs.yaml: {{ toYaml .secret | b64enc | quote }} - {{- end }} - {{- end }} - {{- with .Values.thanosRuler.thanosRulerSpec.objectStorageConfig }} - {{- if and .secret (not .existingSecret) }} - object-storage-configs.yaml: {{ toYaml .secret | b64enc | quote }} - {{- end }} - {{- end }} - {{- with .Values.thanosRuler.thanosRulerSpec.queryConfig }} - {{- if and .secret (not .existingSecret) }} - query-configs.yaml: {{ toYaml .secret | b64enc | quote }} - {{- end }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/service.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/service.yaml deleted file mode 100644 index e2cca29188..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/service.yaml +++ /dev/null @@ -1,57 +0,0 @@ -{{- if .Values.thanosRuler.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - self-monitor: {{ .Values.thanosRuler.serviceMonitor.selfMonitor | quote }} -{{- include "kube-prometheus-stack.labels" . | indent 4 -}} -{{- if .Values.thanosRuler.service.labels }} -{{ toYaml .Values.thanosRuler.service.labels | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.service.annotations }} - annotations: -{{ toYaml .Values.thanosRuler.service.annotations | indent 4 }} -{{- end }} -spec: -{{- if .Values.thanosRuler.service.clusterIP }} - clusterIP: {{ .Values.thanosRuler.service.clusterIP }} -{{- end }} -{{- if .Values.thanosRuler.service.ipDualStack.enabled }} - ipFamilies: {{ toYaml .Values.thanosRuler.service.ipDualStack.ipFamilies | nindent 4 }} - ipFamilyPolicy: {{ .Values.thanosRuler.service.ipDualStack.ipFamilyPolicy }} -{{- end }} -{{- if .Values.thanosRuler.service.externalIPs }} - externalIPs: -{{ toYaml .Values.thanosRuler.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.thanosRuler.service.loadBalancerIP }} - loadBalancerIP: {{ .Values.thanosRuler.service.loadBalancerIP }} -{{- end }} -{{- if .Values.thanosRuler.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{- range $cidr := .Values.thanosRuler.service.loadBalancerSourceRanges }} - - {{ $cidr }} - {{- end }} -{{- end }} -{{- if ne .Values.thanosRuler.service.type "ClusterIP" }} - externalTrafficPolicy: {{ .Values.thanosRuler.service.externalTrafficPolicy }} -{{- end }} - ports: - - name: {{ .Values.thanosRuler.thanosRulerSpec.portName }} - {{- if eq .Values.thanosRuler.service.type "NodePort" }} - nodePort: {{ .Values.thanosRuler.service.nodePort }} - {{- end }} - port: {{ .Values.thanosRuler.service.port }} - targetPort: {{ .Values.thanosRuler.service.targetPort }} - protocol: TCP -{{- if .Values.thanosRuler.service.additionalPorts }} -{{ toYaml .Values.thanosRuler.service.additionalPorts | indent 2 }} -{{- end }} - selector: - app.kubernetes.io/name: thanos-ruler - thanos-ruler: {{ template "kube-prometheus-stack.thanosRuler.crname" . }} - type: "{{ .Values.thanosRuler.service.type }}" -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/serviceaccount.yaml deleted file mode 100644 index b58f1cd4df..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/serviceaccount.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.thanosRuler.enabled .Values.thanosRuler.serviceAccount.create }} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "kube-prometheus-stack.thanosRuler.serviceAccountName" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - app.kubernetes.io/name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - app.kubernetes.io/component: thanos-ruler -{{- include "kube-prometheus-stack.labels" . | indent 4 -}} -{{- if .Values.thanosRuler.serviceAccount.annotations }} - annotations: -{{ toYaml .Values.thanosRuler.serviceAccount.annotations | indent 4 }} -{{- end }} -{{- if .Values.global.imagePullSecrets }} -imagePullSecrets: -{{ toYaml .Values.global.imagePullSecrets | indent 2 }} -{{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/servicemonitor.yaml deleted file mode 100644 index d26ddce93b..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/thanos-ruler/servicemonitor.yaml +++ /dev/null @@ -1,82 +0,0 @@ -{{- if and .Values.thanosRuler.enabled .Values.thanosRuler.serviceMonitor.selfMonitor }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - namespace: {{ template "kube-prometheus-stack.namespace" . }} - labels: - app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} -{{ include "kube-prometheus-stack.labels" . | indent 4 }} -{{- with .Values.thanosRuler.serviceMonitor.additionalLabels }} -{{- toYaml . | nindent 4 }} -{{- end }} -spec: - {{- include "servicemonitor.scrapeLimits" .Values.thanosRuler.serviceMonitor | nindent 2 }} - selector: - matchLabels: - app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} - release: {{ $.Release.Name | quote }} - self-monitor: {{ .Values.thanosRuler.serviceMonitor.selfMonitor | quote }} - namespaceSelector: - matchNames: - - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} - endpoints: - - port: {{ .Values.thanosRuler.thanosRulerSpec.portName }} - {{- if .Values.thanosRuler.serviceMonitor.interval }} - interval: {{ .Values.thanosRuler.serviceMonitor.interval }} - {{- end }} - {{- if .Values.thanosRuler.serviceMonitor.proxyUrl }} - proxyUrl: {{ .Values.thanosRuler.serviceMonitor.proxyUrl}} - {{- end }} - {{- if .Values.thanosRuler.serviceMonitor.scheme }} - scheme: {{ .Values.thanosRuler.serviceMonitor.scheme }} - {{- end }} - {{- if .Values.thanosRuler.serviceMonitor.bearerTokenFile }} - bearerTokenFile: {{ .Values.thanosRuler.serviceMonitor.bearerTokenFile }} - {{- end }} - {{- if .Values.thanosRuler.serviceMonitor.tlsConfig }} - tlsConfig: {{- toYaml .Values.thanosRuler.serviceMonitor.tlsConfig | nindent 6 }} - {{- end }} - path: "{{ trimSuffix "/" .Values.thanosRuler.thanosRulerSpec.routePrefix }}/metrics" - {{- if .Values.thanosRuler.serviceMonitor.metricRelabelings }} - metricRelabelings: {{- tpl (toYaml .Values.thanosRuler.serviceMonitor.metricRelabelings | nindent 6) . }} - {{- end }} - {{ if .Values.global.cattle.clusterId }} - - sourceLabels: [__address__] - targetLabel: cluster_id - replacement: {{ .Values.global.cattle.clusterId }} - {{- end }} - {{ if .Values.global.cattle.clusterName}} - - sourceLabels: [__address__] - targetLabel: cluster_name - replacement: {{ .Values.global.cattle.clusterName }} - {{- end }} - {{- if .Values.thanosRuler.serviceMonitor.relabelings }} - relabelings: {{- toYaml .Values.thanosRuler.serviceMonitor.relabelings | nindent 6 }} - {{- end }} - {{- range .Values.thanosRuler.serviceMonitor.additionalEndpoints }} - - port: {{ .port }} - {{- if or $.Values.thanosRuler.serviceMonitor.interval .interval }} - interval: {{ default $.Values.thanosRuler.serviceMonitor.interval .interval }} - {{- end }} - {{- if or $.Values.thanosRuler.serviceMonitor.proxyUrl .proxyUrl }} - proxyUrl: {{ default $.Values.thanosRuler.serviceMonitor.proxyUrl .proxyUrl }} - {{- end }} - {{- if or $.Values.thanosRuler.serviceMonitor.scheme .scheme }} - scheme: {{ default $.Values.thanosRuler.serviceMonitor.scheme .scheme }} - {{- end }} - {{- if or $.Values.thanosRuler.serviceMonitor.bearerTokenFile .bearerTokenFile }} - bearerTokenFile: {{ default $.Values.thanosRuler.serviceMonitor.bearerTokenFile .bearerTokenFile }} - {{- end }} - {{- if or $.Values.thanosRuler.serviceMonitor.tlsConfig .tlsConfig }} - tlsConfig: {{- default $.Values.thanosRuler.serviceMonitor.tlsConfig .tlsConfig | toYaml | nindent 6 }} - {{- end }} - path: {{ .path }} - {{- if or $.Values.thanosRuler.serviceMonitor.metricRelabelings .metricRelabelings }} - metricRelabelings: {{- tpl (default $.Values.thanosRuler.serviceMonitor.metricRelabelings .metricRelabelings | toYaml | nindent 6) . }} - {{- end }} - {{- if or $.Values.thanosRuler.serviceMonitor.relabelings .relabelings }} - relabelings: {{- default $.Values.thanosRuler.serviceMonitor.relabelings .relabelings | toYaml | nindent 6 }} - {{- end }} - {{- end }} -{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/validate-install-crd.yaml deleted file mode 100644 index 6fcb8b3a69..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/validate-install-crd.yaml +++ /dev/null @@ -1,23 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -# {{- $found := dict -}} -# {{- set $found "monitoring.coreos.com/v1alpha1/AlertmanagerConfig" false -}} -# {{- set $found "monitoring.coreos.com/v1/Alertmanager" false -}} -# {{- set $found "monitoring.coreos.com/v1/PodMonitor" false -}} -# {{- set $found "monitoring.coreos.com/v1/Probe" false -}} -# {{- set $found "monitoring.coreos.com/v1alpha1/PrometheusAgent" false -}} -# {{- set $found "monitoring.coreos.com/v1/Prometheus" false -}} -# {{- set $found "monitoring.coreos.com/v1/PrometheusRule" false -}} -# {{- set $found "monitoring.coreos.com/v1alpha1/ScrapeConfig" false -}} -# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} -# {{- set $found "monitoring.coreos.com/v1/ThanosRuler" false -}} -# {{- range .Capabilities.APIVersions -}} -# {{- if hasKey $found (toString .) -}} -# {{- set $found (toString .) true -}} -# {{- end -}} -# {{- end -}} -# {{- range $_, $exists := $found -}} -# {{- if (eq $exists false) -}} -# {{- required "Required CRDs are missing. Please install the corresponding CRD chart before installing this chart." "" -}} -# {{- end -}} -# {{- end -}} -#{{- end -}} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/validate-psp-install.yaml deleted file mode 100644 index b115feb1af..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/templates/validate-psp-install.yaml +++ /dev/null @@ -1,2 +0,0 @@ -#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} -#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/values.yaml b/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/values.yaml deleted file mode 100644 index b2be1db8db..0000000000 --- a/charts/rancher-monitoring/105.1.0-rc.1+up61.3.2/values.yaml +++ /dev/null @@ -1,5565 +0,0 @@ -# Default values for kube-prometheus-stack. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Rancher Monitoring Configuration - -## Configuration for prometheus-adapter -## ref: https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-adapter -## -prometheus-adapter: - enabled: true - prometheus: - # Change this if you change the namespaceOverride or nameOverride of prometheus-operator - url: http://rancher-monitoring-prometheus.cattle-monitoring-system.svc - port: 9090 - -## RKE PushProx Monitoring -## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox -## -rkeControllerManager: - enabled: false - metricsPort: 10257 # default to secure port as of k8s >= 1.22 - component: kube-controller-manager - clients: - https: - enabled: true - insecureSkipVerify: true - useServiceAccountCredentials: true - port: 10011 - useLocalhost: true - nodeSelector: - node-role.kubernetes.io/controlplane: "true" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - kubeVersionOverrides: - - constraint: "< 1.22" - values: - metricsPort: 10252 # default to insecure port in k8s < 1.22 - clients: - https: - enabled: false - insecureSkipVerify: false - useServiceAccountCredentials: false - -rkeScheduler: - enabled: false - metricsPort: 10259 - component: kube-scheduler - clients: - https: - enabled: true - insecureSkipVerify: true - useServiceAccountCredentials: true - port: 10012 - useLocalhost: true - nodeSelector: - node-role.kubernetes.io/controlplane: "true" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - kubeVersionOverrides: - - constraint: "< 1.23" - values: - metricsPort: 10251 # default to insecure port in k8s < 1.23 - clients: - https: - enabled: false - insecureSkipVerify: false - useServiceAccountCredentials: false - -rkeProxy: - enabled: false - metricsPort: 10249 - component: kube-proxy - clients: - port: 10013 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -rkeEtcd: - enabled: false - metricsPort: 2379 - component: kube-etcd - clients: - port: 10014 - https: - enabled: true - certDir: /etc/kubernetes/ssl - certFile: kube-etcd-*.pem - keyFile: kube-etcd-*-key.pem - caCertFile: kube-ca.pem - seLinuxOptions: - # Gives rkeEtcd permissions to read files in /etc/kubernetes/* - # Type is defined in https://github.com/rancher/rancher-selinux - type: rke_kubereader_t - nodeSelector: - node-role.kubernetes.io/etcd: "true" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -rkeIngressNginx: - enabled: false - metricsPort: 10254 - component: ingress-nginx - clients: - port: 10015 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - nodeSelector: - node-role.kubernetes.io/worker: "true" - -## k3s PushProx Monitoring -## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox -## -k3sServer: - enabled: false - metricsPort: 10250 - component: k3s-server - clients: - port: 10013 - useLocalhost: true - https: - enabled: true - useServiceAccountCredentials: true - insecureSkipVerify: true - rbac: - additionalRules: - - nonResourceURLs: ["/metrics/cadvisor"] - verbs: ["get"] - - apiGroups: [""] - resources: ["nodes/metrics"] - verbs: ["get"] - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - serviceMonitor: - endpoints: - - port: metrics - honorLabels: true - relabelings: - - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - - port: metrics - path: /metrics/cadvisor - honorLabels: true - relabelings: - - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - - port: metrics - path: /metrics/probes - honorLabels: true - relabelings: - - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - -hardened: - k3s: - networkPolicy: - enabled: true - -## KubeADM PushProx Monitoring -## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox -## -kubeAdmControllerManager: - enabled: false - metricsPort: 10257 - component: kube-controller-manager - clients: - port: 10011 - useLocalhost: true - https: - enabled: true - useServiceAccountCredentials: true - insecureSkipVerify: true - nodeSelector: - node-role.kubernetes.io/master: "" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -kubeAdmScheduler: - enabled: false - metricsPort: 10259 - component: kube-scheduler - clients: - port: 10012 - useLocalhost: true - https: - enabled: true - useServiceAccountCredentials: true - insecureSkipVerify: true - nodeSelector: - node-role.kubernetes.io/master: "" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -kubeAdmProxy: - enabled: false - metricsPort: 10249 - component: kube-proxy - clients: - port: 10013 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -kubeAdmEtcd: - enabled: false - metricsPort: 2381 - component: kube-etcd - clients: - port: 10014 - useLocalhost: true - nodeSelector: - node-role.kubernetes.io/master: "" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -## rke2 PushProx Monitoring -## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox -## -rke2ControllerManager: - enabled: false - metricsPort: 10257 # default to secure port as of k8s >= 1.22 - component: kube-controller-manager - clients: - https: - enabled: true - insecureSkipVerify: true - useServiceAccountCredentials: true - port: 10011 - useLocalhost: true - nodeSelector: - node-role.kubernetes.io/master: "true" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - kubeVersionOverrides: - - constraint: "< 1.22" - values: - metricsPort: 10252 # default to insecure port in k8s < 1.22 - clients: - https: - enabled: false - insecureSkipVerify: false - useServiceAccountCredentials: false - -rke2Scheduler: - enabled: false - metricsPort: 10259 # default to secure port as of k8s >= 1.22 - component: kube-scheduler - clients: - https: - enabled: true - insecureSkipVerify: true - useServiceAccountCredentials: true - port: 10012 - useLocalhost: true - nodeSelector: - node-role.kubernetes.io/master: "true" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - kubeVersionOverrides: - - constraint: "< 1.22" - values: - metricsPort: 10251 # default to insecure port in k8s < 1.22 - clients: - https: - enabled: false - insecureSkipVerify: false - useServiceAccountCredentials: false - -rke2Proxy: - enabled: false - metricsPort: 10249 - component: kube-proxy - clients: - port: 10013 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -rke2Etcd: - enabled: false - metricsPort: 2381 - component: kube-etcd - clients: - port: 10014 - useLocalhost: true - nodeSelector: - node-role.kubernetes.io/etcd: "true" - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -rke2IngressNginx: - enabled: false - metricsPort: 10254 - component: ingress-nginx - # in the RKE2 cluster, the ingress-nginx-controller is deployed - # as a non-hostNetwork workload starting at the following versions - # - >= v1.22.12+rke2r1 < 1.23.0-0 - # - >= v1.23.9+rke2r1 < 1.24.0-0 - # - >= v1.24.3+rke2r1 < 1.25.0-0 - # - >= v1.25.0+rke2r1 - # As a result we do not need clients and proxies as we can directly create - # a service that targets the workload with the given app name - namespaceOverride: kube-system - clients: - enabled: false - proxy: - enabled: false - service: - selector: - app.kubernetes.io/name: rke2-ingress-nginx - kubeVersionOverrides: - - constraint: "< 1.21.0-0" - values: - namespaceOverride: "" - clients: - enabled: true - port: 10015 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - affinity: - podAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: "app.kubernetes.io/component" - operator: "In" - values: - - "controller" - topologyKey: "kubernetes.io/hostname" - namespaces: - - "kube-system" - # in the RKE2 cluster, the ingress-nginx-controller is deployed as - # a DaemonSet with 1 pod when RKE2 version is < 1.21.0-0 - deployment: - enabled: false - proxy: - enabled: true - service: - selector: false - - constraint: ">= 1.21.0-0 < 1.22.12-0" - values: - namespaceOverride: "" - clients: - enabled: true - port: 10015 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - affinity: - podAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: "app.kubernetes.io/component" - operator: "In" - values: - - "controller" - topologyKey: "kubernetes.io/hostname" - namespaces: - - "kube-system" - # in the RKE2 cluster, the ingress-nginx-controller is deployed as - # a hostNetwork Deployment with 1 pod when RKE2 version is >= 1.21.0-0 - deployment: - enabled: true - replicas: 1 - proxy: - enabled: true - service: - selector: false - - constraint: ">= 1.23.0-0 < v1.23.9-0" - values: - namespaceOverride: "" - clients: - enabled: true - port: 10015 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - affinity: - podAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: "app.kubernetes.io/component" - operator: "In" - values: - - "controller" - topologyKey: "kubernetes.io/hostname" - namespaces: - - "kube-system" - # in the RKE2 cluster, the ingress-nginx-controller is deployed as - # a hostNetwork Deployment with 1 pod when RKE2 version is >= 1.20.0-0 - deployment: - enabled: true - replicas: 1 - proxy: - enabled: true - service: - selector: false - - constraint: ">= 1.24.0-0 < v1.24.3-0" - values: - namespaceOverride: "" - clients: - enabled: true - port: 10015 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - affinity: - podAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: "app.kubernetes.io/component" - operator: "In" - values: - - "controller" - topologyKey: "kubernetes.io/hostname" - namespaces: - - "kube-system" - # in the RKE2 cluster, the ingress-nginx-controller is deployed as - # a hostNetwork Deployment with 1 pod when RKE2 version is >= 1.20.0-0 - deployment: - enabled: true - replicas: 1 - proxy: - enabled: true - service: - selector: false - - - -## Additional PushProx Monitoring -## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox -## - -# hardenedKubelet can only be deployed if kubelet.enabled=true -# If enabled, it replaces the ServiceMonitor deployed by the default kubelet option with a -# PushProx-based exporter that does not require a host port to be open to scrape metrics. -hardenedKubelet: - enabled: false - metricsPort: 10250 - component: kubelet - clients: - port: 10015 - useLocalhost: true - https: - enabled: true - useServiceAccountCredentials: true - insecureSkipVerify: true - rbac: - additionalRules: - - nonResourceURLs: ["/metrics/cadvisor"] - verbs: ["get"] - - apiGroups: [""] - resources: ["nodes/metrics"] - verbs: ["get"] - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - serviceMonitor: - endpoints: - - port: metrics - honorLabels: true - relabelings: - - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - - port: metrics - path: /metrics/cadvisor - honorLabels: true - relabelings: - - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - - port: metrics - path: /metrics/probes - honorLabels: true - relabelings: - - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - -# hardenedNodeExporter can only be deployed if nodeExporter.enabled=true -# If enabled, it replaces the ServiceMonitor deployed by the default nodeExporter with a -# PushProx-based exporter that does not require a host port to be open to scrape metrics. -hardenedNodeExporter: - enabled: false - metricsPort: 9796 - component: node-exporter - clients: - port: 10016 - useLocalhost: true - tolerations: - - effect: "NoExecute" - operator: "Exists" - - effect: "NoSchedule" - operator: "Exists" - -## Upgrades -upgrade: - ## Run upgrade scripts before an upgrade or rollback via a Job hook - enabled: true - ## Image to use to run the scripts - image: - repository: rancher/shell - tag: v0.2.1 - -## Rancher Monitoring -## - -rancherMonitoring: - enabled: true - - ## A namespaceSelector to identify the namespace to find the Rancher deployment - ## - namespaceSelector: - matchNames: - - cattle-system - - ## A selector to identify the Rancher deployment - ## If not set, the chart will try to search for the Rancher deployment in the cattle-system namespace and infer the selector values from it - ## If the Rancher deployment does not exist, no resources will be deployed. - ## - selector: {} - -## Component scraping nginx-ingress-controller -## -ingressNginx: - enabled: false - - ## The namespace to search for your nginx-ingress-controller - ## - namespace: ingress-nginx - - service: - port: 9913 - targetPort: 10254 - # selector: - # app: ingress-nginx - serviceMonitor: - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "30s" - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## metric relabel configs to apply to samples before ingestion. - ## - metricRelabelings: [] - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - # relabel configs to apply to samples before ingestion. - ## - relabelings: [] - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # targetLabel: nodename - # replacement: $1 - # action: replace - -# Prometheus Operator Configuration - -## Provide a name in place of kube-prometheus-stack for `app:` labels -## NOTE: If you change this value, you must update the prometheus-adapter.prometheus.url -## -nameOverride: "rancher-monitoring" - -## Override the deployment namespace -## NOTE: If you change this value, you must update the prometheus-adapter.prometheus.url -## -namespaceOverride: "cattle-monitoring-system" - -## Provide a k8s version to auto dashboard import script example: kubeTargetVersionOverride: 1.26.6 -## -kubeTargetVersionOverride: "" - -## Allow kubeVersion to be overridden while creating the ingress -## -kubeVersionOverride: "" - -## Provide a name to substitute for the full names of resources -## -fullnameOverride: "" - -## Labels to apply to all resources -## -commonLabels: {} -# scmhash: abc123 -# myLabel: aakkmd - -## Install Prometheus Operator CRDs -## -crds: - enabled: true - -## custom Rules to override "for" and "severity" in defaultRules -## -customRules: {} - # AlertmanagerFailedReload: - # for: 3m - # AlertmanagerMembersInconsistent: - # for: 5m - # severity: "warning" - -## Create default rules for monitoring the cluster -## -defaultRules: - create: true - rules: - alertmanager: true - etcd: true - configReloaders: true - general: true - k8sContainerCpuUsageSecondsTotal: true - k8sContainerMemoryCache: true - k8sContainerMemoryRss: true - k8sContainerMemorySwap: true - k8sContainerResource: true - k8sContainerMemoryWorkingSetBytes: true - k8sPodOwner: true - kubeApiserverAvailability: true - kubeApiserverBurnrate: true - kubeApiserverHistogram: true - kubeApiserverSlos: true - kubeControllerManager: true - kubelet: true - kubeProxy: true - kubePrometheusGeneral: true - kubePrometheusNodeRecording: true - kubernetesApps: true - kubernetesResources: true - kubernetesStorage: true - kubernetesSystem: true - kubeSchedulerAlerting: true - kubeSchedulerRecording: true - kubeStateMetrics: true - network: true - node: true - nodeExporterAlerting: true - nodeExporterRecording: true - prometheus: true - prometheusOperator: true - windows: true - - ## Reduce app namespace alert scope - appNamespacesTarget: ".*" - - ## Set keep_firing_for for all alerts - keepFiringFor: "" - - ## Labels for default rules - labels: {} - ## Annotations for default rules - annotations: {} - - ## Additional labels for PrometheusRule alerts - additionalRuleLabels: {} - - ## Additional annotations for PrometheusRule alerts - additionalRuleAnnotations: {} - - ## Additional labels for specific PrometheusRule alert groups - additionalRuleGroupLabels: - alertmanager: {} - etcd: {} - configReloaders: {} - general: {} - k8sContainerCpuUsageSecondsTotal: {} - k8sContainerMemoryCache: {} - k8sContainerMemoryRss: {} - k8sContainerMemorySwap: {} - k8sContainerResource: {} - k8sPodOwner: {} - kubeApiserverAvailability: {} - kubeApiserverBurnrate: {} - kubeApiserverHistogram: {} - kubeApiserverSlos: {} - kubeControllerManager: {} - kubelet: {} - kubeProxy: {} - kubePrometheusGeneral: {} - kubePrometheusNodeRecording: {} - kubernetesApps: {} - kubernetesResources: {} - kubernetesStorage: {} - kubernetesSystem: {} - kubeSchedulerAlerting: {} - kubeSchedulerRecording: {} - kubeStateMetrics: {} - network: {} - node: {} - nodeExporterAlerting: {} - nodeExporterRecording: {} - prometheus: {} - prometheusOperator: {} - - ## Additional annotations for specific PrometheusRule alerts groups - additionalRuleGroupAnnotations: - alertmanager: {} - etcd: {} - configReloaders: {} - general: {} - k8sContainerCpuUsageSecondsTotal: {} - k8sContainerMemoryCache: {} - k8sContainerMemoryRss: {} - k8sContainerMemorySwap: {} - k8sContainerResource: {} - k8sPodOwner: {} - kubeApiserverAvailability: {} - kubeApiserverBurnrate: {} - kubeApiserverHistogram: {} - kubeApiserverSlos: {} - kubeControllerManager: {} - kubelet: {} - kubeProxy: {} - kubePrometheusGeneral: {} - kubePrometheusNodeRecording: {} - kubernetesApps: {} - kubernetesResources: {} - kubernetesStorage: {} - kubernetesSystem: {} - kubeSchedulerAlerting: {} - kubeSchedulerRecording: {} - kubeStateMetrics: {} - network: {} - node: {} - nodeExporterAlerting: {} - nodeExporterRecording: {} - prometheus: {} - prometheusOperator: {} - - additionalAggregationLabels: [] - - ## Prefix for runbook URLs. Use this to override the first part of the runbookURLs that is common to all rules. - runbookUrl: "https://runbooks.prometheus-operator.dev/runbooks" - - ## Disabled PrometheusRule alerts - disabled: {} - # KubeAPIDown: true - # NodeRAIDDegraded: true - -## Deprecated way to provide custom recording or alerting rules to be deployed into the cluster. -## -# additionalPrometheusRules: [] -# - name: my-rule-file -# groups: -# - name: my_group -# rules: -# - record: my_record -# expr: 100 * my_record - -## Provide custom recording or alerting rules to be deployed into the cluster. -## -additionalPrometheusRulesMap: {} -# rule-name: -# groups: -# - name: my_group -# rules: -# - record: my_record -# expr: 100 * my_record - -## -global: - cattle: - - systemDefaultRegistry: "" - ## Windows Monitoring - ## ref: https://github.com/rancher/charts/tree/dev-v2.5-source/packages/rancher-windows-exporter - ## - ## Deploys a DaemonSet of Prometheus exporters based on https://github.com/prometheus-community/windows_exporter. - ## Every Windows host must have a wins version of 0.1.0+ to use this chart (default as of Rancher 2.5.8). - ## To upgrade wins versions on Windows hosts, see https://github.com/rancher/wins/tree/master/charts/rancher-wins-upgrader. - ## - windows: - enabled: false - seLinux: - enabled: false - kubectl: - repository: rancher/kubectl - tag: v1.20.2 - pullPolicy: IfNotPresent - rbac: - ## Create RBAC resources for ServiceAccounts and users - ## - create: true - - userRoles: - ## Create default user ClusterRoles to allow users to interact with Prometheus CRs, ConfigMaps, and Secrets - create: true - ## Aggregate default user ClusterRoles into default k8s ClusterRoles - aggregateToDefaultRoles: true - - ## Create ClusterRoles that extend the existing view, edit and admin ClusterRoles to interact with prometheus-operator CRDs - ## Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles - createAggregateClusterRoles: false - - pspAnnotations: {} - ## Specify pod annotations - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp - ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl - ## - # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' - # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' - # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' - - ## Global image registry to use if it needs to be overriden for some specific use cases (e.g local registries, custom images, ...) - ## - imageRegistry: "docker.io" - - ## Reference to one or more secrets to be used when pulling images - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - imagePullSecrets: [] - # - name: "image-pull-secret" - # or - # - "image-pull-secret" - -windowsMonitoring: - ## Deploys the windows-exporter and Windows-specific dashboards and rules (job name must be 'windows-exporter') - enabled: false - -loggingMonitors: - ## Deploys logging-specific dashboards, make sure to also set metrics.serviceMonitor to true in the logging chart for both fluentd and fluentbit - fluentd: - enabled: false - fluentbit: - enabled: false - -## Configuration for prometheus-windows-exporter -## ref: https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-windows-exporter -## -prometheus-windows-exporter: - ## Enable ServiceMonitor and set Kubernetes label to use as a job label - ## - prometheus: - monitor: - enabled: true - jobLabel: jobLabel - - releaseLabel: true - - ## Set job label to 'windows-exporter' as required by the default Prometheus rules and Grafana dashboards - ## - podLabels: - jobLabel: windows-exporter - - ## Enable memory and container metrics as required by the default Prometheus rules and Grafana dashboards - ## - config: |- - collectors: - enabled: '[defaults],memory,container' - -## Configuration for alertmanager -## ref: https://prometheus.io/docs/alerting/alertmanager/ -## -alertmanager: - - ## Deploy alertmanager - ## - enabled: true - - ## Annotations for Alertmanager - ## - annotations: {} - - ## Api that prometheus will use to communicate with alertmanager. Possible values are v1, v2 - ## - apiVersion: v2 - - ## @param alertmanager.enableFeatures Enable access to Alertmanager disabled features. - ## - enableFeatures: [] - - ## Service account for Alertmanager to use. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ - ## - serviceAccount: - create: true - name: "" - annotations: {} - automountServiceAccountToken: true - - ## Configure pod disruption budgets for Alertmanager - ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget - ## - podDisruptionBudget: - enabled: false - minAvailable: 1 - maxUnavailable: "" - - ## Alertmanager configuration directives - ## ref: https://prometheus.io/docs/alerting/configuration/#configuration-file - ## https://prometheus.io/webtools/alerting/routing-tree-editor/ - ## - config: - global: - resolve_timeout: 5m - inhibit_rules: - - source_matchers: - - 'severity = critical' - target_matchers: - - 'severity =~ warning|info' - equal: - - 'namespace' - - 'alertname' - - source_matchers: - - 'severity = warning' - target_matchers: - - 'severity = info' - equal: - - 'namespace' - - 'alertname' - - source_matchers: - - 'alertname = InfoInhibitor' - target_matchers: - - 'severity = info' - equal: - - 'namespace' - - target_matchers: - - 'alertname = InfoInhibitor' - route: - group_by: ['namespace'] - group_wait: 30s - group_interval: 5m - repeat_interval: 12h - receiver: 'null' - routes: - - receiver: 'null' - matchers: - - alertname = "Watchdog" - receivers: - - name: 'null' - templates: - - '/etc/alertmanager/config/*.tmpl' - - ## Alertmanager configuration directives (as string type, preferred over the config hash map) - ## stringConfig will be used only, if tplConfig is true - ## ref: https://prometheus.io/docs/alerting/configuration/#configuration-file - ## https://prometheus.io/webtools/alerting/routing-tree-editor/ - ## - stringConfig: "" - - ## Pass the Alertmanager configuration directives through Helm's templating - ## engine. If the Alertmanager configuration contains Alertmanager templates, - ## they'll need to be properly escaped so that they are not interpreted by - ## Helm - ## ref: https://helm.sh/docs/developing_charts/#using-the-tpl-function - ## https://prometheus.io/docs/alerting/configuration/#tmpl_string - ## https://prometheus.io/docs/alerting/notifications/ - ## https://prometheus.io/docs/alerting/notification_examples/ - tplConfig: false - - ## Alertmanager template files to format alerts - ## By default, templateFiles are placed in /etc/alertmanager/config/ and if - ## they have a .tmpl file suffix will be loaded. See config.templates above - ## to change, add other suffixes. If adding other suffixes, be sure to update - ## config.templates above to include those suffixes. - ## ref: https://prometheus.io/docs/alerting/notifications/ - ## https://prometheus.io/docs/alerting/notification_examples/ - ## - templateFiles: - rancher_defaults.tmpl: |- - {{- define "slack.rancher.text" -}} - {{ template "rancher.text_multiple" . }} - {{- end -}} - - {{- define "rancher.text_multiple" -}} - *[GROUP - Details]* - One or more alarms in this group have triggered a notification. - - {{- if gt (len .GroupLabels.Values) 0 }} - *Group Labels:* - {{- range .GroupLabels.SortedPairs }} - • *{{ .Name }}:* `{{ .Value }}` - {{- end }} - {{- end }} - {{- if .ExternalURL }} - *Link to AlertManager:* {{ .ExternalURL }} - {{- end }} - - {{- range .Alerts }} - {{ template "rancher.text_single" . }} - {{- end }} - {{- end -}} - - {{- define "rancher.text_single" -}} - {{- if .Labels.alertname }} - *[ALERT - {{ .Labels.alertname }}]* - {{- else }} - *[ALERT]* - {{- end }} - {{- if .Labels.severity }} - *Severity:* `{{ .Labels.severity }}` - {{- end }} - {{- if .Labels.cluster }} - *Cluster:* {{ .Labels.cluster }} - {{- end }} - {{- if .Annotations.summary }} - *Summary:* {{ .Annotations.summary }} - {{- end }} - {{- if .Annotations.message }} - *Message:* {{ .Annotations.message }} - {{- end }} - {{- if .Annotations.description }} - *Description:* {{ .Annotations.description }} - {{- end }} - {{- if .Annotations.runbook_url }} - *Runbook URL:* <{{ .Annotations.runbook_url }}|:spiral_note_pad:> - {{- end }} - {{- with .Labels }} - {{- with .Remove (stringSlice "alertname" "severity" "cluster") }} - {{- if gt (len .) 0 }} - *Additional Labels:* - {{- range .SortedPairs }} - • *{{ .Name }}:* `{{ .Value }}` - {{- end }} - {{- end }} - {{- end }} - {{- end }} - {{- with .Annotations }} - {{- with .Remove (stringSlice "summary" "message" "description" "runbook_url") }} - {{- if gt (len .) 0 }} - *Additional Annotations:* - {{- range .SortedPairs }} - • *{{ .Name }}:* `{{ .Value }}` - {{- end }} - {{- end }} - {{- end }} - {{- end }} - {{- end -}} - - ingress: - 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 - - annotations: {} - - labels: {} - - ## Override ingress to a different defined port on the service - # servicePort: 8081 - ## Override ingress to a different service then the default, this is useful if you need to - ## point to a specific instance of the alertmanager (eg kube-prometheus-stack-alertmanager-0) - # serviceName: kube-prometheus-stack-alertmanager-0 - - ## Hosts must be provided if Ingress is enabled. - ## - hosts: [] - # - alertmanager.domain.com - - ## Paths to use for ingress rules - one path should match the alertmanagerSpec.routePrefix - ## - paths: [] - # - / - - ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) - ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types - # pathType: ImplementationSpecific - - ## TLS configuration for Alertmanager Ingress - ## Secret must be manually created in the namespace - ## - tls: [] - # - secretName: alertmanager-general-tls - # hosts: - # - alertmanager.example.com - - ## Configuration for Alertmanager secret - ## - secret: - annotations: {} - - # by default the alertmanager secret is not overwritten if it already exists - recreateIfExists: false - - ## Configuration for creating an Ingress that will map to each Alertmanager replica service - ## alertmanager.servicePerReplica must be enabled - ## - ingressPerReplica: - 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 - - annotations: {} - labels: {} - - ## Final form of the hostname for each per replica ingress is - ## {{ ingressPerReplica.hostPrefix }}-{{ $replicaNumber }}.{{ ingressPerReplica.hostDomain }} - ## - ## Prefix for the per replica ingress that will have `-$replicaNumber` - ## appended to the end - hostPrefix: "" - ## Domain that will be used for the per replica ingress - hostDomain: "" - - ## Paths to use for ingress rules - ## - paths: [] - # - / - - ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) - ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types - # pathType: ImplementationSpecific - - ## Secret name containing the TLS certificate for alertmanager per replica ingress - ## Secret must be manually created in the namespace - tlsSecretName: "" - - ## Separated secret for each per replica Ingress. Can be used together with cert-manager - ## - tlsSecretPerReplica: - enabled: false - ## Final form of the secret for each per replica ingress is - ## {{ tlsSecretPerReplica.prefix }}-{{ $replicaNumber }} - ## - prefix: "alertmanager" - - ## Configuration for Alertmanager service - ## - service: - annotations: {} - labels: {} - clusterIP: "" - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - - ## Port for Alertmanager Service to listen on - ## - port: 9093 - ## To be used with a proxy extraContainer port - ## - targetPort: 9093 - ## Port to expose on each node - ## Only used if service.type is 'NodePort' - ## - nodePort: 30903 - ## List of IP addresses at which the Prometheus server service is available - ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips - ## - - ## Additional ports to open for Alertmanager service - ## - additionalPorts: [] - # - name: oauth-proxy - # port: 8081 - # targetPort: 8081 - # - name: oauth-metrics - # port: 8082 - # targetPort: 8082 - - externalIPs: [] - loadBalancerIP: "" - loadBalancerSourceRanges: [] - - ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints - ## - externalTrafficPolicy: Cluster - - ## If you want to make sure that connections from a particular client are passed to the same Pod each time - ## Accepts 'ClientIP' or 'None' - ## - sessionAffinity: None - - ## If you want to modify the ClientIP sessionAffinity timeout - ## The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP" - ## - sessionAffinityConfig: - clientIP: - timeoutSeconds: 10800 - - ## Service type - ## - type: ClusterIP - - ## Configuration for creating a separate Service for each statefulset Alertmanager replica - ## - servicePerReplica: - enabled: false - annotations: {} - - ## Port for Alertmanager Service per replica to listen on - ## - port: 9093 - - ## To be used with a proxy extraContainer port - targetPort: 9093 - - ## Port to expose on each node - ## Only used if servicePerReplica.type is 'NodePort' - ## - nodePort: 30904 - - ## Loadbalancer source IP ranges - ## Only used if servicePerReplica.type is "LoadBalancer" - loadBalancerSourceRanges: [] - - ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints - ## - externalTrafficPolicy: Cluster - - ## Service type - ## - type: ClusterIP - - ## Configuration for creating a ServiceMonitor for AlertManager - ## - serviceMonitor: - ## If true, a ServiceMonitor will be created for the AlertManager service. - ## - selfMonitor: true - - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## Additional labels - ## - additionalLabels: {} - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS. - scheme: "" - - ## enableHttp2: Whether to enable HTTP2. - ## See https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#endpoint - enableHttp2: true - - ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS. - ## Of type: https://github.com/coreos/prometheus-operator/blob/main/Documentation/api.md#tlsconfig - tlsConfig: {} - - bearerTokenFile: - - ## 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__] - - ## 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 - - ## Additional Endpoints - ## - additionalEndpoints: [] - # - port: oauth-metrics - # path: /metrics - - ## Settings affecting alertmanagerSpec - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#alertmanagerspec - ## - alertmanagerSpec: - ## Standard object's metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata - ## Metadata Labels and Annotations gets propagated to the Alertmanager pods. - ## - podMetadata: {} - - ## Image of Alertmanager - ## - image: - repository: rancher/mirrored-prometheus-alertmanager - tag: v0.27.0 - sha: "" - - ## If true then the user will be responsible to provide a secret with alertmanager configuration - ## So when true the config part will be ignored (including templateFiles) and the one in the secret will be used - ## - useExistingSecret: false - - ## Secrets is a list of Secrets in the same namespace as the Alertmanager object, which shall be mounted into the - ## Alertmanager Pods. The Secrets are mounted into /etc/alertmanager/secrets/. - ## - secrets: [] - - ## If false then the user will opt out of automounting API credentials. - ## - automountServiceAccountToken: true - - ## ConfigMaps is a list of ConfigMaps in the same namespace as the Alertmanager object, which shall be mounted into the Alertmanager Pods. - ## The ConfigMaps are mounted into /etc/alertmanager/configmaps/. - ## - configMaps: [] - - ## ConfigSecret is the name of a Kubernetes Secret in the same namespace as the Alertmanager object, which contains configuration for - ## this Alertmanager instance. Defaults to 'alertmanager-' The secret is mounted into /etc/alertmanager/config. - ## - # configSecret: - - ## WebTLSConfig defines the TLS parameters for HTTPS - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#alertmanagerwebspec - web: {} - - ## AlertmanagerConfigs to be selected to merge and configure Alertmanager with. - ## - alertmanagerConfigSelector: {} - ## Example which selects all alertmanagerConfig resources - ## with label "alertconfig" with values any of "example-config" or "example-config-2" - # alertmanagerConfigSelector: - # matchExpressions: - # - key: alertconfig - # operator: In - # values: - # - example-config - # - example-config-2 - # - ## Example which selects all alertmanagerConfig resources with label "role" set to "example-config" - # alertmanagerConfigSelector: - # matchLabels: - # role: example-config - - ## Namespaces to be selected for AlertmanagerConfig discovery. If nil, only check own namespace. - ## - alertmanagerConfigNamespaceSelector: {} - ## Example which selects all namespaces - ## with label "alertmanagerconfig" with values any of "example-namespace" or "example-namespace-2" - # alertmanagerConfigNamespaceSelector: - # matchExpressions: - # - key: alertmanagerconfig - # operator: In - # values: - # - example-namespace - # - example-namespace-2 - - ## Example which selects all namespaces with label "alertmanagerconfig" set to "enabled" - # alertmanagerConfigNamespaceSelector: - # matchLabels: - # alertmanagerconfig: enabled - - ## AlermanagerConfig to be used as top level configuration - ## - alertmanagerConfiguration: {} - ## Example with select a global alertmanagerconfig - # alertmanagerConfiguration: - # name: global-alertmanager-Configuration - - ## Defines the strategy used by AlertmanagerConfig objects to match alerts. eg: - ## - alertmanagerConfigMatcherStrategy: {} - ## Example with use OnNamespace strategy - # alertmanagerConfigMatcherStrategy: - # type: OnNamespace - - ## Define Log Format - # Use logfmt (default) or json logging - logFormat: logfmt - - ## Log level for Alertmanager to be configured with. - ## - logLevel: info - - ## Size is the expected size of the alertmanager cluster. The controller will eventually make the size of the - ## running cluster equal to the expected size. - replicas: 1 - - ## Time duration Alertmanager shall retain data for. Default is '120h', and must match the regular expression - ## [0-9]+(ms|s|m|h) (milliseconds seconds minutes hours). - ## - retention: 120h - - ## Storage is the definition of how storage will be used by the Alertmanager instances. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/storage.md - ## - storage: {} - # volumeClaimTemplate: - # spec: - # storageClassName: gluster - # accessModes: ["ReadWriteOnce"] - # resources: - # requests: - # storage: 50Gi - # selector: {} - - - ## The external URL the Alertmanager instances will be available under. This is necessary to generate correct URLs. This is necessary if Alertmanager is not served from root of a DNS name. string false - ## - externalUrl: - - ## The route prefix Alertmanager registers HTTP handlers for. This is useful, if using ExternalURL and a proxy is rewriting HTTP routes of a request, and the actual ExternalURL is still true, - ## but the server serves requests under a different route prefix. For example for use with kubectl proxy. - ## - routePrefix: / - - ## scheme: HTTP scheme to use. Can be used with `tlsConfig` for example if using istio mTLS. - scheme: "" - - ## tlsConfig: TLS configuration to use when connect to the endpoint. For example if using istio mTLS. - ## Of type: https://github.com/coreos/prometheus-operator/blob/main/Documentation/api.md#tlsconfig - tlsConfig: {} - - ## If set to true all actions on the underlying managed objects are not going to be performed, except for delete actions. - ## - paused: false - - ## Define which Nodes the Pods are scheduled on. - ## ref: https://kubernetes.io/docs/user-guide/node-selection/ - ## - nodeSelector: {} - - ## Define resources requests and limits for single Pods. - ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: - limits: - memory: 500Mi - cpu: 1000m - requests: - memory: 100Mi - cpu: 100m - - ## Pod anti-affinity can prevent the scheduler from placing Prometheus replicas on the same node. - ## The default value "soft" means that the scheduler should *prefer* to not schedule two replica pods onto the same node but no guarantee is provided. - ## The value "hard" means that the scheduler is *required* to not schedule two replica pods onto the same node. - ## The value "" will disable pod anti-affinity so that no anti-affinity rules will be configured. - ## - podAntiAffinity: "" - - ## If anti-affinity is enabled sets the topologyKey to use for anti-affinity. - ## This can be changed to, for example, failure-domain.beta.kubernetes.io/zone - ## - podAntiAffinityTopologyKey: kubernetes.io/hostname - - ## Assign custom affinity rules to the alertmanager instance - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - ## - affinity: {} - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/e2e-az-name - # operator: In - # values: - # - e2e-az1 - # - e2e-az2 - - ## If specified, the pod's tolerations. - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - ## - tolerations: [] - # - key: "key" - # operator: "Equal" - # value: "value" - # effect: "NoSchedule" - - ## If specified, the pod's topology spread constraints. - ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ - ## - topologySpreadConstraints: [] - # - maxSkew: 1 - # topologyKey: topology.kubernetes.io/zone - # whenUnsatisfiable: DoNotSchedule - # labelSelector: - # matchLabels: - # app: alertmanager - - ## SecurityContext holds pod-level security attributes and common container settings. - ## This defaults to non root user with uid 1000 and gid 2000. *v1.PodSecurityContext false - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - ## - securityContext: - runAsGroup: 2000 - runAsNonRoot: true - runAsUser: 1000 - fsGroup: 2000 - seccompProfile: - type: RuntimeDefault - - ## ListenLocal makes the Alertmanager server listen on loopback, so that it does not bind against the Pod IP. - ## Note this is only for the Alertmanager UI, not the gossip communication. - ## - listenLocal: false - - ## Containers allows injecting additional containers. This is meant to allow adding an authentication proxy to an Alertmanager pod. - ## - containers: [] - # containers: - # - name: oauth-proxy - # image: quay.io/oauth2-proxy/oauth2-proxy:v7.5.1 - # args: - # - --upstream=http://127.0.0.1:9093 - # - --http-address=0.0.0.0:8081 - # - --metrics-address=0.0.0.0:8082 - # - ... - # ports: - # - containerPort: 8081 - # name: oauth-proxy - # protocol: TCP - # - containerPort: 8082 - # name: oauth-metrics - # protocol: TCP - # resources: {} - - # Additional volumes on the output StatefulSet definition. - volumes: [] - - # Additional VolumeMounts on the output StatefulSet definition. - volumeMounts: [] - - ## InitContainers allows injecting additional initContainers. This is meant to allow doing some changes - ## (permissions, dir tree) on mounted volumes before starting prometheus - initContainers: [] - - ## Priority class assigned to the Pods - ## - priorityClassName: "" - - ## AdditionalPeers allows injecting a set of additional Alertmanagers to peer with to form a highly available cluster. - ## - additionalPeers: [] - - ## PortName to use for Alert Manager. - ## - portName: "http-web" - - ## ClusterAdvertiseAddress is the explicit address to advertise in cluster. Needs to be provided for non RFC1918 [1] (public) addresses. [1] RFC1918: https://tools.ietf.org/html/rfc1918 - ## - clusterAdvertiseAddress: false - - ## clusterGossipInterval determines interval between gossip attempts. - ## Needs to be specified as GoDuration, a time duration that can be parsed by Go’s time.ParseDuration() (e.g. 45ms, 30s, 1m, 1h20m15s) - clusterGossipInterval: "" - - ## clusterPeerTimeout determines timeout for cluster peering. - ## Needs to be specified as GoDuration, a time duration that can be parsed by Go’s time.ParseDuration() (e.g. 45ms, 30s, 1m, 1h20m15s) - clusterPeerTimeout: "" - - ## clusterPushpullInterval determines interval between pushpull attempts. - ## Needs to be specified as GoDuration, a time duration that can be parsed by Go’s time.ParseDuration() (e.g. 45ms, 30s, 1m, 1h20m15s) - clusterPushpullInterval: "" - - ## ForceEnableClusterMode ensures Alertmanager does not deactivate the cluster mode when running with a single replica. - ## Use case is e.g. spanning an Alertmanager cluster across Kubernetes clusters with a single replica in each. - forceEnableClusterMode: false - - ## Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to - ## be considered available. Defaults to 0 (pod will be considered available as soon as it is ready). - minReadySeconds: 0 - - ## Additional configuration which is not covered by the properties above. (passed through tpl) - additionalConfig: {} - - ## Additional configuration which is not covered by the properties above. - ## Useful, if you need advanced templating inside alertmanagerSpec. - ## Otherwise, use alertmanager.alertmanagerSpec.additionalConfig (passed through tpl) - additionalConfigString: "" - - ## ExtraSecret can be used to store various data in an extra secret - ## (use it for example to store hashed basic auth credentials) - extraSecret: - ## if not set, name will be auto generated - # name: "" - annotations: {} - data: {} - # auth: | - # foo:$apr1$OFG3Xybp$ckL0FHDAkoXYIlH9.cysT0 - # someoneelse:$apr1$DMZX2Z4q$6SbQIfyuLQd.xmo/P0m2c. - -## Using default values from https://github.com/grafana/helm-charts/blob/main/charts/grafana/values.yaml -## -grafana: - enabled: true - namespaceOverride: "" - - ## Grafana's primary configuration - ## NOTE: values in map will be converted to ini format - ## ref: http://docs.grafana.org/installation/configuration/ - ## - grafana.ini: - users: - auto_assign_org_role: Viewer - auth: - disable_login_form: false - auth.anonymous: - enabled: true - org_role: Viewer - auth.basic: - enabled: false - dashboards: - # Modify this value to change the default dashboard shown on the main Grafana page - default_home_dashboard_path: /tmp/dashboards/rancher-default-home.json - security: - # Required to embed dashboards in Rancher Cluster Overview Dashboard on Cluster Explorer - allow_embedding: true - - deploymentStrategy: - type: Recreate - - ## ForceDeployDatasources Create datasource configmap even if grafana deployment has been disabled - ## - forceDeployDatasources: false - - ## ForceDeployDashboard Create dashboard configmap even if grafana deployment has been disabled - ## - forceDeployDashboards: false - - ## Deploy default dashboards - ## - defaultDashboardsEnabled: true - - # Additional options for defaultDashboards - defaultDashboards: - # The default namespace to place defaultDashboards within - namespace: cattle-dashboards - # Whether to create the default namespace as a Helm managed namespace or use an existing namespace - # If false, the defaultDashboards.namespace will be created as a Helm managed namespace - useExistingNamespace: false - # Whether the Helm managed namespace created by this chart should be left behind on a Helm uninstall - # If you place other dashboards in this namespace, then they will be deleted on a helm uninstall - # Ignore if useExistingNamespace is true - cleanupOnUninstall: false - - ## Timezone for the default dashboards - ## Other options are: browser or a specific timezone, i.e. Europe/Luxembourg - ## - defaultDashboardsTimezone: utc - - ## Editable flag for the default dashboards - ## - defaultDashboardsEditable: true - - adminPassword: prom-operator - - rbac: - ## If true, Grafana PSPs will be created - ## - pspEnabled: false - - ingress: - ## If true, Grafana Ingress will be created - ## - enabled: false - - ## IngressClassName for Grafana Ingress. - ## Should be provided if Ingress is enable. - ## - # ingressClassName: nginx - - ## Annotations for Grafana Ingress - ## - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - - ## Labels to be added to the Ingress - ## - labels: {} - - ## Hostnames. - ## Must be provided if Ingress is enable. - ## - # hosts: - # - grafana.domain.com - hosts: [] - - ## Path for grafana ingress - path: / - - ## TLS configuration for grafana Ingress - ## Secret must be manually created in the namespace - ## - tls: [] - # - secretName: grafana-general-tls - # hosts: - # - grafana.example.com - - # # To make Grafana persistent (Using Statefulset) - # # - # persistence: - # enabled: true - # type: sts - # storageClassName: "storageClassName" - # accessModes: - # - ReadWriteOnce - # size: 20Gi - # finalizers: - # - kubernetes.io/pvc-protection - - serviceAccount: - create: true - autoMount: true - - sidecar: - dashboards: - enabled: true - label: grafana_dashboard - searchNamespace: cattle-dashboards - labelValue: "1" - - # Support for new table panels, when enabled grafana auto migrates the old table panels to newer table panels - enableNewTablePanelSyntax: false - - ## Annotations for Grafana dashboard configmaps - ## - annotations: {} - multicluster: - global: - enabled: false - etcd: - enabled: false - provider: - allowUiUpdates: false - datasources: - enabled: true - defaultDatasourceEnabled: true - isDefaultDatasource: true - - name: Prometheus - uid: prometheus - - ## URL of prometheus datasource - ## - # url: http://prometheus-stack-prometheus:9090/ - - ## Prometheus request timeout in seconds - # timeout: 30 - - # If not defined, will use prometheus.prometheusSpec.scrapeInterval or its default - # defaultDatasourceScrapeInterval: 15s - - ## Annotations for Grafana datasource configmaps - ## - annotations: {} - - ## Set method for HTTP to send query to datasource - httpMethod: POST - - ## Create datasource for each Pod of Prometheus StatefulSet; - ## this uses headless service `prometheus-operated` which is - ## created by Prometheus Operator - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/0fee93e12dc7c2ea1218f19ae25ec6b893460590/pkg/prometheus/statefulset.go#L255-L286 - createPrometheusReplicasDatasources: false - label: grafana_datasource - labelValue: "1" - - ## Field with internal link pointing to existing data source in Grafana. - ## Can be provisioned via additionalDataSources - exemplarTraceIdDestinations: {} - # datasourceUid: Jaeger - # traceIdLabelName: trace_id - alertmanager: - enabled: true - name: Alertmanager - uid: alertmanager - handleGrafanaManagedAlerts: false - implementation: prometheus - - extraConfigmapMounts: [] - # - name: certs-configmap - # mountPath: /etc/grafana/ssl/ - # configMap: certs-configmap - # readOnly: true - - deleteDatasources: [] - # - name: example-datasource - # orgId: 1 - - ## Configure additional grafana datasources (passed through tpl) - ## ref: http://docs.grafana.org/administration/provisioning/#datasources - additionalDataSources: [] - # - name: prometheus-sample - # access: proxy - # basicAuth: true - # basicAuthPassword: pass - # basicAuthUser: daco - # editable: false - # jsonData: - # tlsSkipVerify: true - # orgId: 1 - # type: prometheus - # url: https://{{ printf "%s-prometheus.svc" .Release.Name }}:9090 - # version: 1 - - ## Passed to grafana subchart and used by servicemonitor below - ## - service: - portName: nginx-http - ## Port for Grafana Service to listen on - ## - port: 80 - ## To be used with a proxy extraContainer port - ## - targetPort: 8080 - ## Port to expose on each node - ## Only used if service.type is 'NodePort' - ## - nodePort: 30950 - ## Service type - ## - type: ClusterIP - - ipFamilies: [] - ipFamilyPolicy: "" - - proxy: - image: - repository: rancher/mirrored-library-nginx - tag: 1.24.0-alpine - - ## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod - extraContainers: | - - name: grafana-proxy - args: - - nginx - - -g - - daemon off; - - -c - - /nginx/nginx.conf - image: "{{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }}" - ports: - - containerPort: 8080 - name: nginx-http - protocol: TCP - volumeMounts: - - mountPath: /nginx - name: grafana-nginx - - mountPath: /var/cache/nginx - name: nginx-home - securityContext: - runAsUser: 101 - runAsGroup: 101 - - ## Volumes that can be used in containers - extraContainerVolumes: - - name: nginx-home - emptyDir: {} - - name: grafana-nginx - configMap: - name: grafana-nginx-proxy-config - items: - - key: nginx.conf - mode: 438 - path: nginx.conf - - ## If true, create a serviceMonitor for grafana - ## - serviceMonitor: - # If true, a ServiceMonitor CRD is created for a prometheus operator - # https://github.com/coreos/prometheus-operator - # - enabled: true - - # Path to use for scraping metrics. Might be different if server.root_url is set - # in grafana.ini - path: "/metrics" - - # namespace: monitoring (defaults to use the namespace this chart is deployed to) - - # labels for the ServiceMonitor - labels: {} - - # Scrape interval. If not set, the Prometheus default scrape interval is used. - # - interval: "" - scheme: http - tlsConfig: {} - scrapeTimeout: 30s - - ## 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 - - resources: - limits: - memory: 200Mi - cpu: 200m - requests: - memory: 100Mi - cpu: 100m - - testFramework: - enabled: false - -## Flag to disable all the kubernetes component scrapers -## -kubernetesServiceMonitors: - enabled: true - -## Component scraping the kube api server -## -kubeApiServer: - enabled: true - tlsConfig: - serverName: kubernetes - insecureSkipVerify: false - serviceMonitor: - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - jobLabel: component - selector: - matchLabels: - component: apiserver - provider: kubernetes - - ## 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: - # Drop excessively noisy apiserver buckets. - - action: drop - regex: apiserver_request_duration_seconds_bucket;(0.15|0.2|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2|3|3.5|4|4.5|6|7|8|9|15|25|40|50) - sourceLabels: - - __name__ - - le - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - ## 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_namespace - # - __meta_kubernetes_service_name - # - __meta_kubernetes_endpoint_port_name - # action: keep - # regex: default;kubernetes;https - # - targetLabel: __address__ - # replacement: kubernetes.default.svc:443 - - ## Additional labels - ## - additionalLabels: {} - # foo: bar - -## Component scraping the kubelet and kubelet-hosted cAdvisor -## -kubelet: - enabled: true - namespace: kube-system - - serviceMonitor: - ## Attach metadata to discovered targets. Requires Prometheus v2.45 for endpoints created by the operator. - ## - attachMetadata: - node: false - - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## If true, Prometheus use (respect) labels provided by exporter. - ## - honorLabels: true - - ## If true, Prometheus ingests metrics with timestamp provided by exporter. If false, Prometheus ingests metrics with timestamp of scrape. - ## - honorTimestamps: true - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## Enable scraping the kubelet over https. For requirements to enable this see - ## https://github.com/prometheus-operator/prometheus-operator/issues/926 - ## - https: true - - ## Skip TLS certificate validation when scraping. - ## This is enabled by default because kubelet serving certificate deployed by kubeadm is by default self-signed - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#kubelet-serving-certs - ## - insecureSkipVerify: true - - ## Enable scraping /metrics/cadvisor from kubelet's service - ## - cAdvisor: true - - ## Enable scraping /metrics/probes from kubelet's service - ## - probes: true - - ## Enable scraping /metrics/resource from kubelet's service - ## This is disabled by default because container metrics are already exposed by cAdvisor - ## - resource: false - # From kubernetes 1.18, /metrics/resource/v1alpha1 renamed to /metrics/resource - resourcePath: "/metrics/resource/v1alpha1" - - ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - cAdvisorMetricRelabelings: - # Drop less useful container CPU metrics. - - sourceLabels: [__name__] - action: drop - regex: 'container_cpu_(cfs_throttled_seconds_total|load_average_10s|system_seconds_total|user_seconds_total)' - # Drop less useful container / always zero filesystem metrics. - - sourceLabels: [__name__] - action: drop - regex: 'container_fs_(io_current|io_time_seconds_total|io_time_weighted_seconds_total|reads_merged_total|sector_reads_total|sector_writes_total|writes_merged_total)' - # Drop less useful / always zero container memory metrics. - - sourceLabels: [__name__] - action: drop - regex: 'container_memory_(mapped_file|swap)' - # Drop less useful container process metrics. - - sourceLabels: [__name__] - action: drop - regex: 'container_(file_descriptors|tasks_state|threads_max)' - # Drop container spec metrics that overlap with kube-state-metrics. - - sourceLabels: [__name__] - action: drop - regex: 'container_spec.*' - # Drop cgroup metrics with no pod. - - sourceLabels: [id, pod] - action: drop - regex: '.+;' - # - sourceLabels: [__name__, image] - # separator: ; - # regex: container_([a-z_]+); - # replacement: $1 - # action: drop - # - sourceLabels: [__name__] - # separator: ; - # regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) - # replacement: $1 - # action: drop - - ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - probesMetricRelabelings: [] - # - sourceLabels: [__name__, image] - # separator: ; - # regex: container_([a-z_]+); - # replacement: $1 - # action: drop - # - sourceLabels: [__name__] - # separator: ; - # regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) - # replacement: $1 - # action: drop - - ## RelabelConfigs to apply to samples before scraping - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - ## metrics_path is required to match upstream rules and charts - cAdvisorRelabelings: - - action: replace - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # targetLabel: nodename - # replacement: $1 - # action: replace - - ## RelabelConfigs to apply to samples before scraping - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - probesRelabelings: - - action: replace - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # targetLabel: nodename - # replacement: $1 - # action: replace - - ## RelabelConfigs to apply to samples before scraping - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - resourceRelabelings: - - action: replace - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # targetLabel: nodename - # replacement: $1 - # action: replace - - ## 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: [] - # - sourceLabels: [__name__, image] - # separator: ; - # regex: container_([a-z_]+); - # replacement: $1 - # action: drop - # - sourceLabels: [__name__] - # separator: ; - # regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) - # replacement: $1 - # action: drop - - ## RelabelConfigs to apply to samples before scraping - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - ## metrics_path is required to match upstream rules and charts - relabelings: - - action: replace - sourceLabels: [__metrics_path__] - targetLabel: metrics_path - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # targetLabel: nodename - # replacement: $1 - # action: replace - - ## Additional labels - ## - additionalLabels: {} - # foo: bar - -## Component scraping the kube controller manager -## -kubeControllerManager: - enabled: false - - ## If your kube controller manager is not deployed as a pod, specify IPs it can be found on - ## - endpoints: [] - # - 10.141.4.22 - # - 10.141.4.23 - # - 10.141.4.24 - - ## If using kubeControllerManager.endpoints only the port and targetPort are used - ## - service: - enabled: true - ## If null or unset, the value is determined dynamically based on target Kubernetes version due to change - ## of default port in Kubernetes 1.22. - ## - port: null - targetPort: null - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - # selector: - # component: kube-controller-manager - - serviceMonitor: - enabled: true - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## port: Name of the port the metrics will be scraped from - ## - port: http-metrics - - jobLabel: jobLabel - selector: {} - # matchLabels: - # component: kube-controller-manager - - ## Enable scraping kube-controller-manager over https. - ## Requires proper certs (not self-signed) and delegated authentication/authorization checks. - ## If null or unset, the value is determined dynamically based on target Kubernetes version. - ## - https: null - - # Skip TLS certificate validation when scraping - insecureSkipVerify: null - - # Name of the server to use when validating TLS certificate - serverName: null - - ## 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__] - - ## 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 - - ## Additional labels - ## - additionalLabels: {} - # foo: bar - -## Component scraping coreDns. Use either this or kubeDns -## -coreDns: - enabled: true - service: - enabled: true - port: 9153 - targetPort: 9153 - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - # selector: - # k8s-app: kube-dns - serviceMonitor: - enabled: true - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## port: Name of the port the metrics will be scraped from - ## - port: http-metrics - - jobLabel: jobLabel - selector: {} - # matchLabels: - # k8s-app: kube-dns - - ## 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__] - - ## 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 - - ## Additional labels - ## - additionalLabels: {} - # foo: bar - -## Component scraping kubeDns. Use either this or coreDns -## -kubeDns: - enabled: false - service: - dnsmasq: - port: 10054 - targetPort: 10054 - skydns: - port: 10055 - targetPort: 10055 - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - # selector: - # k8s-app: kube-dns - serviceMonitor: - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - jobLabel: jobLabel - selector: {} - # matchLabels: - # k8s-app: kube-dns - - ## 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__] - - ## 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 - - ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - dnsmasqMetricRelabelings: [] - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - ## RelabelConfigs to apply to samples before scraping - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - dnsmasqRelabelings: [] - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # targetLabel: nodename - # replacement: $1 - # action: replace - - ## Additional labels - ## - additionalLabels: {} - # foo: bar - -## Component scraping etcd -## -kubeEtcd: - enabled: false - - ## If your etcd is not deployed as a pod, specify IPs it can be found on - ## - endpoints: [] - # - 10.141.4.22 - # - 10.141.4.23 - # - 10.141.4.24 - - ## Etcd service. If using kubeEtcd.endpoints only the port and targetPort are used - ## - service: - enabled: true - port: 2381 - targetPort: 2381 - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - # selector: - # component: etcd - - ## Configure secure access to the etcd cluster by loading a secret into prometheus and - ## specifying security configuration below. For example, with a secret named etcd-client-cert - ## - ## serviceMonitor: - ## scheme: https - ## insecureSkipVerify: false - ## serverName: localhost - ## caFile: /etc/prometheus/secrets/etcd-client-cert/etcd-ca - ## certFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client - ## keyFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client-key - ## - serviceMonitor: - enabled: true - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - scheme: http - insecureSkipVerify: false - serverName: "" - caFile: "" - certFile: "" - keyFile: "" - - ## port: Name of the port the metrics will be scraped from - ## - port: http-metrics - - jobLabel: jobLabel - selector: {} - # matchLabels: - # component: etcd - - ## 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__] - - ## 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 - - ## Additional labels - ## - additionalLabels: {} - # foo: bar - -## Component scraping kube scheduler -## -kubeScheduler: - enabled: false - - ## If your kube scheduler is not deployed as a pod, specify IPs it can be found on - ## - endpoints: [] - # - 10.141.4.22 - # - 10.141.4.23 - # - 10.141.4.24 - - ## If using kubeScheduler.endpoints only the port and targetPort are used - ## - service: - enabled: true - ## If null or unset, the value is determined dynamically based on target Kubernetes version due to change - ## of default port in Kubernetes 1.23. - ## - port: null - targetPort: null - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - # selector: - # component: kube-scheduler - - serviceMonitor: - enabled: true - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - ## Enable scraping kube-scheduler over https. - ## Requires proper certs (not self-signed) and delegated authentication/authorization checks. - ## If null or unset, the value is determined dynamically based on target Kubernetes version. - ## - https: null - - ## port: Name of the port the metrics will be scraped from - ## - port: http-metrics - - jobLabel: jobLabel - selector: {} - # matchLabels: - # component: kube-scheduler - - ## Skip TLS certificate validation when scraping - insecureSkipVerify: null - - ## Name of the server to use when validating TLS certificate - serverName: null - - ## 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__] - - ## 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 - - ## Additional labels - ## - additionalLabels: {} - # foo: bar - -## Component scraping kube proxy -## -kubeProxy: - enabled: false - - ## If your kube proxy is not deployed as a pod, specify IPs it can be found on - ## - endpoints: [] - # - 10.141.4.22 - # - 10.141.4.23 - # - 10.141.4.24 - - service: - enabled: true - port: 10249 - targetPort: 10249 - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - # selector: - # k8s-app: kube-proxy - - serviceMonitor: - enabled: true - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## port: Name of the port the metrics will be scraped from - ## - port: http-metrics - - jobLabel: jobLabel - selector: {} - # matchLabels: - # k8s-app: kube-proxy - - ## Enable scraping kube-proxy over https. - ## Requires proper certs (not self-signed) and delegated authentication/authorization checks - ## - https: false - - ## 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__] - - ## RelabelConfigs to apply to samples before scraping - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig - ## - relabelings: [] - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - ## Additional labels - ## - additionalLabels: {} - # foo: bar - -## Component scraping kube state metrics -## -kubeStateMetrics: - enabled: true - -## Configuration for kube-state-metrics subchart -## -kube-state-metrics: - namespaceOverride: "" - rbac: - create: true - releaseLabel: true - prometheus: - monitor: - enabled: true - - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## Scrape Timeout. If not set, the Prometheus default scrape timeout is used. - ## - scrapeTimeout: "" - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - # Keep labels from scraped data, overriding server-side labels - ## - honorLabels: true - - ## 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__] - - ## 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 - - selfMonitor: - enabled: false - -## Deploy node exporter as a daemonset to all nodes -## -nodeExporter: - enabled: true - operatingSystems: - linux: - enabled: true - darwin: - enabled: true - - ## ForceDeployDashboard Create dashboard configmap even if nodeExporter deployment has been disabled - ## - forceDeployDashboards: false - -## Configuration for prometheus-node-exporter subchart -## -prometheus-node-exporter: - namespaceOverride: "" - podLabels: - ## Add the 'node-exporter' label to be used by serviceMonitor to match standard common usage in rules and grafana dashboards - ## - jobLabel: node-exporter - releaseLabel: true - extraArgs: - - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($|/) - - --collector.filesystem.fs-types-exclude=^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$ - service: - portName: http-metrics - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - prometheus: - monitor: - enabled: true - - jobLabel: jobLabel - - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## How long until a scrape request times out. If not set, the Prometheus default scape timeout is used. - ## - scrapeTimeout: "" - - ## proxyUrl: URL of a proxy that should be used for scraping. - ## - proxyUrl: "" - - ## 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: [] - # - sourceLabels: [__name__] - # separator: ; - # regex: ^node_mountstats_nfs_(event|operations|transport)_.+ - # replacement: $1 - # action: drop - - ## 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 - rbac: - ## If true, create PSPs for node-exporter - ## - pspEnabled: false - -## Manages Prometheus and Alertmanager components -## -prometheusOperator: - enabled: true - - ## Use '{{ template "kube-prometheus-stack.fullname" . }}-operator' by default - fullnameOverride: "" - - ## Number of old replicasets to retain ## - ## The default value is 10, 0 will garbage-collect old replicasets ## - revisionHistoryLimit: 10 - - ## Strategy of the deployment - ## - strategy: {} - - ## Prometheus-Operator v0.39.0 and later support TLS natively. - ## - tls: - enabled: true - # Value must match version names from https://golang.org/pkg/crypto/tls/#pkg-constants - tlsMinVersion: VersionTLS13 - # The default webhook port is 10250 in order to work out-of-the-box in GKE private clusters and avoid adding firewall rules. - internalPort: 10250 - - ## Admission webhook support for PrometheusRules resources added in Prometheus Operator 0.30 can be enabled to prevent incorrectly formatted - ## rules from making their way into prometheus and potentially preventing the container from starting - admissionWebhooks: - ## Valid values: Fail, Ignore, IgnoreOnInstallOnly - ## IgnoreOnInstallOnly - If Release.IsInstall returns "true", set "Ignore" otherwise "Fail" - failurePolicy: "" - ## The default timeoutSeconds is 10 and the maximum value is 30. - timeoutSeconds: 10 - enabled: true - ## A PEM encoded CA bundle which will be used to validate the webhook's server certificate. - ## If unspecified, system trust roots on the apiserver are used. - caBundle: "" - ## If enabled, generate a self-signed certificate, then patch the webhook configurations with the generated data. - ## On chart upgrades (or if the secret exists) the cert will not be re-generated. You can use this to provide your own - ## certs ahead of time if you wish. - ## - annotations: {} - # argocd.argoproj.io/hook: PreSync - # argocd.argoproj.io/hook-delete-policy: HookSucceeded - - namespaceSelector: {} - objectSelector: {} - - - deployment: - enabled: false - - ## Number of replicas - ## - replicas: 1 - - ## Strategy of the deployment - ## - strategy: {} - - # Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ - podDisruptionBudget: {} - # maxUnavailable: 1 - # minAvailable: 1 - - ## Number of old replicasets to retain ## - ## The default value is 10, 0 will garbage-collect old replicasets ## - revisionHistoryLimit: 10 - - ## Prometheus-Operator v0.39.0 and later support TLS natively. - ## - tls: - enabled: true - # Value must match version names from https://golang.org/pkg/crypto/tls/#pkg-constants - tlsMinVersion: VersionTLS13 - # The default webhook port is 10250 in order to work out-of-the-box in GKE private clusters and avoid adding firewall rules. - internalPort: 10250 - - ## Service account for Prometheus Operator Webhook to use. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ - ## - serviceAccount: - automountServiceAccountToken: false - create: true - name: "" - - ## Configuration for Prometheus operator Webhook service - ## - service: - annotations: {} - labels: {} - clusterIP: "" - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - - ## Port to expose on each node - ## Only used if service.type is 'NodePort' - ## - nodePort: 31080 - - nodePortTls: 31443 - - ## Additional ports to open for Prometheus operator Webhook service - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services - ## - additionalPorts: [] - - ## Loadbalancer IP - ## Only use if service.type is "LoadBalancer" - ## - loadBalancerIP: "" - loadBalancerSourceRanges: [] - - ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints - ## - externalTrafficPolicy: Cluster - - ## Service type - ## NodePort, ClusterIP, LoadBalancer - ## - type: ClusterIP - - ## List of IP addresses at which the Prometheus server service is available - ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips - ## - externalIPs: [] - - # ## Labels to add to the operator webhook deployment - # ## - labels: {} - - ## Annotations to add to the operator webhook deployment - ## - annotations: {} - - ## Labels to add to the operator webhook pod - ## - podLabels: {} - - ## Annotations to add to the operator webhook pod - ## - podAnnotations: {} - - ## Assign a PriorityClassName to pods if set - # priorityClassName: "" - - ## Define Log Format - # Use logfmt (default) or json logging - # logFormat: logfmt - - ## Decrease log verbosity to errors only - # logLevel: error - - ## Prometheus-operator webhook image - ## - image: - registry: quay.io - repository: rancher/mirrored-prometheus-operator-admission-webhook - # if not set appVersion field from Chart.yaml is used - tag: v0.75.1 - sha: "" - pullPolicy: IfNotPresent - - ## Define Log Format - # Use logfmt (default) or json logging - # logFormat: logfmt - - ## Decrease log verbosity to errors only - # logLevel: error - - - ## Liveness probe - ## - livenessProbe: - enabled: true - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - - ## Readiness probe - ## - readinessProbe: - enabled: true - failureThreshold: 3 - initialDelaySeconds: 5 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - - ## Resource limits & requests - ## - resources: {} - # limits: - # cpu: 200m - # memory: 200Mi - # requests: - # cpu: 100m - # memory: 100Mi - - # Required for use in managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico), - # because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working - ## - hostNetwork: false - - ## Define which Nodes the Pods are scheduled on. - ## ref: https://kubernetes.io/docs/user-guide/node-selection/ - ## - nodeSelector: {} - - ## Tolerations for use with node taints - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - ## - tolerations: [] - # - key: "key" - # operator: "Equal" - # value: "value" - # effect: "NoSchedule" - - ## Assign custom affinity rules to the prometheus operator - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - ## - affinity: {} - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/e2e-az-name - # operator: In - # values: - # - e2e-az1 - # - e2e-az2 - dnsConfig: {} - # nameservers: - # - 1.2.3.4 - # searches: - # - ns1.svc.cluster-domain.example - # - my.dns.search.suffix - # options: - # - name: ndots - # value: "2" - # - name: edns0 - securityContext: - fsGroup: 65534 - runAsGroup: 65534 - runAsNonRoot: true - runAsUser: 65534 - seccompProfile: - type: RuntimeDefault - - ## Container-specific security context configuration - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - ## - containerSecurityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - - ## If false then the user will opt out of automounting API credentials. - ## - automountServiceAccountToken: true - - patch: - enabled: true - image: - repository: rancher/mirrored-ingress-nginx-kube-webhook-certgen - tag: v1.4.3 - sha: "" - pullPolicy: IfNotPresent - resources: {} - ## Provide a priority class name to the webhook patching job - ## - priorityClassName: "" - ttlSecondsAfterFinished: 60 - annotations: {} - # argocd.argoproj.io/hook: PreSync - # argocd.argoproj.io/hook-delete-policy: HookSucceeded - podAnnotations: {} - nodeSelector: {} - affinity: {} - tolerations: [] - - ## SecurityContext holds pod-level security attributes and common container settings. - ## This defaults to non root user with uid 2000 and gid 2000. *v1.PodSecurityContext false - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - ## - securityContext: - runAsGroup: 2000 - runAsNonRoot: true - runAsUser: 2000 - seccompProfile: - type: RuntimeDefault - ## Service account for Prometheus Operator Webhook Job Patch to use. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ - ## - serviceAccount: - create: true - automountServiceAccountToken: true - - # Security context for create job container - createSecretJob: - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - - # Security context for patch job container - patchWebhookJob: - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - - # Use certmanager to generate webhook certs - certManager: - enabled: false - # self-signed root certificate - rootCert: - duration: "" # default to be 5y - admissionCert: - duration: "" # default to be 1y - # issuerRef: - # name: "issuer" - # kind: "ClusterIssuer" - - ## Namespaces to scope the interaction of the Prometheus Operator and the apiserver (allow list). - ## This is mutually exclusive with denyNamespaces. Setting this to an empty object will disable the configuration - ## - namespaces: {} - # releaseNamespace: true - # additional: - # - kube-system - - ## Namespaces not to scope the interaction of the Prometheus Operator (deny list). - ## - denyNamespaces: [] - - ## Filter namespaces to look for prometheus-operator custom resources - ## - alertmanagerInstanceNamespaces: [] - alertmanagerConfigNamespaces: [] - prometheusInstanceNamespaces: [] - thanosRulerInstanceNamespaces: [] - - ## The clusterDomain value will be added to the cluster.peer option of the alertmanager. - ## Without this specified option cluster.peer will have value alertmanager-monitoring-alertmanager-0.alertmanager-operated:9094 (default value) - ## With this specified option cluster.peer will have value alertmanager-monitoring-alertmanager-0.alertmanager-operated.namespace.svc.cluster-domain:9094 - ## - # clusterDomain: "cluster.local" - - networkPolicy: - ## Enable creation of NetworkPolicy resources. - ## - enabled: false - - ## Flavor of the network policy to use. - # Can be: - # * kubernetes for networking.k8s.io/v1/NetworkPolicy - # * cilium for cilium.io/v2/CiliumNetworkPolicy - flavor: kubernetes - - # cilium: - # egress: - - ## match labels used in selector - # matchLabels: {} - - ## Service account for Prometheus Operator to use. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ - ## - serviceAccount: - create: true - name: "" - automountServiceAccountToken: true - - ## Configuration for Prometheus operator service - ## - service: - annotations: {} - labels: {} - clusterIP: "" - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - - ## Port to expose on each node - ## Only used if service.type is 'NodePort' - ## - nodePort: 30080 - - nodePortTls: 30443 - - ## Additional ports to open for Prometheus operator service - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services - ## - additionalPorts: [] - - ## Loadbalancer IP - ## Only use if service.type is "LoadBalancer" - ## - loadBalancerIP: "" - loadBalancerSourceRanges: [] - - ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints - ## - externalTrafficPolicy: Cluster - - ## Service type - ## NodePort, ClusterIP, LoadBalancer - ## - type: ClusterIP - - ## List of IP addresses at which the Prometheus server service is available - ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips - ## - externalIPs: [] - - # ## Labels to add to the operator deployment - # ## - labels: {} - - ## Annotations to add to the operator deployment - ## - annotations: {} - - ## Labels to add to the operator pod - ## - podLabels: {} - - ## Annotations to add to the operator pod - ## - podAnnotations: {} - - ## Assign a PriorityClassName to pods if set - # priorityClassName: "" - - ## Define Log Format - # Use logfmt (default) or json logging - # logFormat: logfmt - - ## Decrease log verbosity to errors only - # logLevel: error - - kubeletService: - ## If true, the operator will create and maintain a service for scraping kubelets - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/helm/prometheus-operator/README.md - ## - enabled: true - namespace: kube-system - selector: "" - ## Use '{{ template "kube-prometheus-stack.fullname" . }}-kubelet' by default - name: "" - - ## Create a servicemonitor for the operator - ## - serviceMonitor: - ## If true, create a serviceMonitor for prometheus operator - ## - selfMonitor: true - - ## Labels for ServiceMonitor - additionalLabels: {} - - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## Scrape timeout. If not set, the Prometheus default scrape timeout is used. - scrapeTimeout: "" - - ## Metric relabel configs to apply to samples before ingestion. - ## - metricRelabelings: [] - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - # relabel configs to apply to samples before ingestion. - ## - relabelings: [] - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # targetLabel: nodename - # replacement: $1 - # action: replace - - ## Resource limits & requests - ## - resources: {} - # limits: - # cpu: 200m - # memory: 200Mi - # requests: - # cpu: 100m - # memory: 100Mi - - ## Operator Environment - ## env: - ## VARIABLE: value - env: - GOGC: "30" - - # Required for use in managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico), - # because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working - ## - hostNetwork: false - - ## Define which Nodes the Pods are scheduled on. - ## ref: https://kubernetes.io/docs/user-guide/node-selection/ - ## - nodeSelector: {} - - ## Tolerations for use with node taints - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - ## - tolerations: [] - # - key: "key" - # operator: "Equal" - # value: "value" - # effect: "NoSchedule" - - ## Assign custom affinity rules to the prometheus operator - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - ## - affinity: {} - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/e2e-az-name - # operator: In - # values: - # - e2e-az1 - # - e2e-az2 - dnsConfig: {} - # nameservers: - # - 1.2.3.4 - # searches: - # - ns1.svc.cluster-domain.example - # - my.dns.search.suffix - # options: - # - name: ndots - # value: "2" - # - name: edns0 - securityContext: - fsGroup: 65534 - runAsGroup: 65534 - runAsNonRoot: true - runAsUser: 65534 - seccompProfile: - type: RuntimeDefault - - ## Container-specific security context configuration - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - ## - containerSecurityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - - # Enable vertical pod autoscaler support for prometheus-operator - verticalPodAutoscaler: - enabled: false - - # Recommender 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: - # - name: custom-recommender-performance - - # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory - controlledResources: [] - # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. - # controlledValues: RequestsAndLimits - - # Define the max allowed resources for the pod - maxAllowed: {} - # cpu: 200m - # memory: 100Mi - # Define the min allowed resources for the pod - minAllowed: {} - # cpu: 200m - # memory: 100Mi - - 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 - - ## Prometheus-operator image - ## - image: - repository: rancher/mirrored-prometheus-operator-prometheus-operator - tag: v0.75.1 - sha: "" - pullPolicy: IfNotPresent - - ## Prometheus image to use for prometheuses managed by the operator - ## - # prometheusDefaultBaseImage: prometheus/prometheus - - ## Prometheus image registry to use for prometheuses managed by the operator - ## - # prometheusDefaultBaseImageRegistry: quay.io - - ## Alertmanager image to use for alertmanagers managed by the operator - ## - # alertmanagerDefaultBaseImage: prometheus/alertmanager - - ## Alertmanager image registry to use for alertmanagers managed by the operator - ## - # alertmanagerDefaultBaseImageRegistry: quay.io - - ## Prometheus-config-reloader - ## - prometheusConfigReloader: - image: - repository: rancher/mirrored-prometheus-operator-prometheus-config-reloader - tag: v0.75.1 - sha: "" - - # add prometheus config reloader liveness and readiness probe. Default: false - enableProbe: false - - # resource config for prometheusConfigReloader - resources: {} - # requests: - # cpu: 200m - # memory: 50Mi - # limits: - # cpu: 200m - # memory: 50Mi - - ## Thanos side-car image when configured - ## - thanosImage: - repository: rancher/mirrored-thanos-thanos - tag: v0.35.1 - sha: "" - - ## Set a Label Selector to filter watched prometheus and prometheusAgent - ## - prometheusInstanceSelector: "" - - ## Set a Label Selector to filter watched alertmanager - ## - alertmanagerInstanceSelector: "" - - ## Set a Label Selector to filter watched thanosRuler - thanosRulerInstanceSelector: "" - - ## Set a Field Selector to filter watched secrets - ## - secretFieldSelector: "type!=kubernetes.io/dockercfg,type!=kubernetes.io/service-account-token,type!=helm.sh/release.v1" - - ## If false then the user will opt out of automounting API credentials. - ## - automountServiceAccountToken: true - - ## Additional volumes - ## - extraVolumes: [] - - ## Additional volume mounts - ## - extraVolumeMounts: [] - -## Deploy a Prometheus instance -## -prometheus: - enabled: true - - ## Toggle prometheus into agent mode - ## Note many of features described below (e.g. rules, query, alerting, remote read, thanos) will not work in agent mode. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/designs/prometheus-agent.md - ## - agentMode: false - - ## Annotations for Prometheus - ## - annotations: {} - - ## Configure network policy for the prometheus - networkPolicy: - enabled: false - - ## Flavor of the network policy to use. - # Can be: - # * kubernetes for networking.k8s.io/v1/NetworkPolicy - # * cilium for cilium.io/v2/CiliumNetworkPolicy - flavor: kubernetes - - # cilium: - # endpointSelector: - # egress: - # ingress: - - # egress: - # - {} - # ingress: - # - {} - # podSelector: - # matchLabels: - # app: prometheus - - ## Service account for Prometheuses to use. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ - ## - serviceAccount: - create: true - name: "" - annotations: {} - automountServiceAccountToken: true - - # Service for thanos service discovery on sidecar - # Enable this can make Thanos Query can use - # `--store=dnssrv+_grpc._tcp.${kube-prometheus-stack.fullname}-thanos-discovery.${namespace}.svc.cluster.local` to discovery - # Thanos sidecar on prometheus nodes - # (Please remember to change ${kube-prometheus-stack.fullname} and ${namespace}. Not just copy and paste!) - thanosService: - enabled: false - annotations: {} - labels: {} - - ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints - ## - externalTrafficPolicy: Cluster - - ## Service type - ## - type: ClusterIP - - ## Service dual stack - ## - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - - ## gRPC port config - portName: grpc - port: 10901 - targetPort: "grpc" - - ## HTTP port config (for metrics) - httpPortName: http - httpPort: 10902 - targetHttpPort: "http" - - ## ClusterIP to assign - # Default is to make this a headless service ("None") - clusterIP: "None" - - ## Port to expose on each node, if service type is NodePort - ## - nodePort: 30901 - httpNodePort: 30902 - - # ServiceMonitor to scrape Sidecar metrics - # Needs thanosService to be enabled as well - thanosServiceMonitor: - enabled: false - interval: "" - - ## Additional labels - ## - additionalLabels: {} - - ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS. - scheme: "" - - ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS. - ## Of type: https://github.com/coreos/prometheus-operator/blob/main/Documentation/api.md#tlsconfig - tlsConfig: {} - - bearerTokenFile: - - ## Metric relabel configs to apply to samples before ingestion. - metricRelabelings: [] - - ## relabel configs to apply to samples before ingestion. - relabelings: [] - - # Service for external access to sidecar - # Enabling this creates a service to expose thanos-sidecar outside the cluster. - thanosServiceExternal: - enabled: false - annotations: {} - labels: {} - loadBalancerIP: "" - loadBalancerSourceRanges: [] - - ## gRPC port config - portName: grpc - port: 10901 - targetPort: "grpc" - - ## HTTP port config (for metrics) - httpPortName: http - httpPort: 10902 - targetHttpPort: "http" - - ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints - ## - externalTrafficPolicy: Cluster - - ## Service type - ## - type: LoadBalancer - - ## Port to expose on each node - ## - nodePort: 30901 - httpNodePort: 30902 - - ## Configuration for Prometheus service - ## - service: - annotations: {} - labels: {} - clusterIP: "" - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - - ## Port for Prometheus Service to listen on - ## - port: 9090 - - ## To be used with a proxy extraContainer port - targetPort: 8081 - - ## Port for Prometheus Reloader to listen on - ## - reloaderWebPort: 8080 - - ## List of IP addresses at which the Prometheus server service is available - ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips - ## - externalIPs: [] - - ## Port to expose on each node - ## Only used if service.type is 'NodePort' - ## - nodePort: 30090 - - ## Loadbalancer IP - ## Only use if service.type is "LoadBalancer" - loadBalancerIP: "" - loadBalancerSourceRanges: [] - - ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints - ## - externalTrafficPolicy: Cluster - - ## Service type - ## - type: ClusterIP - - ## Additional ports to open for Prometheus service - ## - additionalPorts: [] - # additionalPorts: - # - name: oauth-proxy - # port: 8081 - # targetPort: 8081 - # - name: oauth-metrics - # port: 8082 - # targetPort: 8082 - - ## Consider that all endpoints are considered "ready" even if the Pods themselves are not - ## Ref: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec - publishNotReadyAddresses: false - - ## If you want to make sure that connections from a particular client are passed to the same Pod each time - ## Accepts 'ClientIP' or 'None' - ## - sessionAffinity: None - - ## If you want to modify the ClientIP sessionAffinity timeout - ## The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP" - ## - sessionAffinityConfig: - clientIP: - timeoutSeconds: 10800 - - ## Configuration for creating a separate Service for each statefulset Prometheus replica - ## - servicePerReplica: - enabled: false - annotations: {} - - ## Port for Prometheus Service per replica to listen on - ## - port: 9090 - - ## To be used with a proxy extraContainer port - targetPort: 9090 - - ## Port to expose on each node - ## Only used if servicePerReplica.type is 'NodePort' - ## - nodePort: 30091 - - ## Loadbalancer source IP ranges - ## Only used if servicePerReplica.type is "LoadBalancer" - loadBalancerSourceRanges: [] - - ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints - ## - externalTrafficPolicy: Cluster - - ## Service type - ## - type: ClusterIP - - ## Service dual stack - ## - ipDualStack: - enabled: false - ipFamilies: ["IPv6", "IPv4"] - ipFamilyPolicy: "PreferDualStack" - - ## Configure pod disruption budgets for Prometheus - ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget - ## - podDisruptionBudget: - enabled: false - minAvailable: 1 - maxUnavailable: "" - - # Ingress exposes thanos sidecar outside the cluster - thanosIngress: - 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 - - annotations: {} - labels: {} - servicePort: 10901 - - ## Port to expose on each node - ## Only used if service.type is 'NodePort' - ## - nodePort: 30901 - - ## Hosts must be provided if Ingress is enabled. - ## - hosts: [] - # - thanos-gateway.domain.com - - ## Paths to use for ingress rules - ## - paths: [] - # - / - - ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) - ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types - # pathType: ImplementationSpecific - - ## TLS configuration for Thanos Ingress - ## Secret must be manually created in the namespace - ## - tls: [] - # - secretName: thanos-gateway-tls - # hosts: - # - thanos-gateway.domain.com - # - - ## ExtraSecret can be used to store various data in an extra secret - ## (use it for example to store hashed basic auth credentials) - extraSecret: - ## if not set, name will be auto generated - # name: "" - annotations: {} - data: {} - # auth: | - # foo:$apr1$OFG3Xybp$ckL0FHDAkoXYIlH9.cysT0 - # someoneelse:$apr1$DMZX2Z4q$6SbQIfyuLQd.xmo/P0m2c. - - ingress: - 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 - - annotations: {} - labels: {} - - ## Redirect ingress to an additional defined port on the service - # servicePort: 8081 - - ## Hostnames. - ## Must be provided if Ingress is enabled. - ## - # hosts: - # - prometheus.domain.com - hosts: [] - - ## Paths to use for ingress rules - one path should match the prometheusSpec.routePrefix - ## - paths: [] - # - / - - ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) - ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types - # pathType: ImplementationSpecific - - ## TLS configuration for Prometheus Ingress - ## Secret must be manually created in the namespace - ## - tls: [] - # - secretName: prometheus-general-tls - # hosts: - # - prometheus.example.com - - ## Configuration for creating an Ingress that will map to each Prometheus replica service - ## prometheus.servicePerReplica must be enabled - ## - ingressPerReplica: - 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 - - annotations: {} - labels: {} - - ## Final form of the hostname for each per replica ingress is - ## {{ ingressPerReplica.hostPrefix }}-{{ $replicaNumber }}.{{ ingressPerReplica.hostDomain }} - ## - ## Prefix for the per replica ingress that will have `-$replicaNumber` - ## appended to the end - hostPrefix: "" - ## Domain that will be used for the per replica ingress - hostDomain: "" - - ## Paths to use for ingress rules - ## - paths: [] - # - / - - ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) - ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types - # pathType: ImplementationSpecific - - ## Secret name containing the TLS certificate for Prometheus per replica ingress - ## Secret must be manually created in the namespace - tlsSecretName: "" - - ## Separated secret for each per replica Ingress. Can be used together with cert-manager - ## - tlsSecretPerReplica: - enabled: false - ## Final form of the secret for each per replica ingress is - ## {{ tlsSecretPerReplica.prefix }}-{{ $replicaNumber }} - ## - prefix: "prometheus" - - ## Configure additional options for default pod security policy for Prometheus - ## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ - podSecurityPolicy: - allowedCapabilities: [] - allowedHostPaths: [] - volumes: [] - - serviceMonitor: - ## If true, create a serviceMonitor for prometheus - ## - selfMonitor: true - - ## Scrape interval. If not set, the Prometheus default scrape interval is used. - ## - interval: "" - - ## Additional labels - ## - additionalLabels: {} - - ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - ## - sampleLimit: 0 - - ## TargetLimit defines a limit on the number of scraped targets that will be accepted. - ## - targetLimit: 0 - - ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelLimit: 0 - - ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelNameLengthLimit: 0 - - ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. - ## - labelValueLengthLimit: 0 - - ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS. - scheme: "" - - ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS. - ## Of type: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#tlsconfig - tlsConfig: {} - - bearerTokenFile: - - ## Metric relabel configs to apply to samples before ingestion. - ## - metricRelabelings: [] - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - # relabel configs to apply to samples before ingestion. - ## - relabelings: [] - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # targetLabel: nodename - # replacement: $1 - # action: replace - - ## Additional Endpoints - ## - additionalEndpoints: [] - # - port: oauth-metrics - # path: /metrics - - ## Settings affecting prometheusSpec - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#prometheusspec - ## - prometheusSpec: - ## Statefulset's persistent volume claim retention policy - ## pvcDeleteOnStsDelete and pvcDeleteOnStsScale determine whether - ## statefulset's PVCs are deleted (true) or retained (false) on scaling down - ## and deleting statefulset, respectively. Requires 1.27.0+. - ## Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#persistentvolumeclaim-retention - persistentVolumeClaimRetentionPolicy: {} - # whenDeleted: Retain - # whenScaled: Retain - - ## If true, pass --storage.tsdb.max-block-duration=2h to prometheus. This is already done if using Thanos - ## - ## AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in the pod, - ## If the field isn’t set, the operator mounts the service account token by default. - ## Warning: be aware that by default, Prometheus requires the service account token for Kubernetes service discovery, - ## It is possible to use strategic merge patch to project the service account token into the ‘prometheus’ container. - automountServiceAccountToken: true - - disableCompaction: false - ## APIServerConfig - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#apiserverconfig - ## - apiserverConfig: {} - - ## Allows setting additional arguments for the Prometheus container - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.Prometheus - additionalArgs: [] - - ## Interval between consecutive scrapes. - ## Defaults to 30s. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/release-0.44/pkg/prometheus/promcfg.go#L180-L183 - ## - scrapeInterval: "30s" - - ## Number of seconds to wait for target to respond before erroring - ## - # scrapeTimeout: "" - - ## List of scrape classes to expose to scraping objects such as - ## PodMonitors, ServiceMonitors, Probes and ScrapeConfigs. - ## - scrapeClasses: [] - # - name: istio-mtls - # default: false - # tlsConfig: - # caFile: /etc/prometheus/secrets/istio.default/root-cert.pem - # certFile: /etc/prometheus/secrets/istio.default/cert-chain.pem - - ## Interval between consecutive evaluations. - ## - evaluationInterval: "30s" - - ## ListenLocal makes the Prometheus server listen on loopback, so that it does not bind against the Pod IP. - ## - listenLocal: false - - ## EnableAdminAPI enables Prometheus the administrative HTTP API which includes functionality such as deleting time series. - ## This is disabled by default. - ## ref: https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-admin-apis - ## - enableAdminAPI: false - - ## Sets version of Prometheus overriding the Prometheus version as derived - ## from the image tag. Useful in cases where the tag does not follow semver v2. - version: "" - - ## WebTLSConfig defines the TLS parameters for HTTPS - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#webtlsconfig - web: {} - - ## Exemplars related settings that are runtime reloadable. - ## It requires to enable the exemplar storage feature to be effective. - exemplars: "" - ## Maximum number of exemplars stored in memory for all series. - ## If not set, Prometheus uses its default value. - ## A value of zero or less than zero disables the storage. - # maxSize: 100000 - - # EnableFeatures API enables access to Prometheus disabled features. - # ref: https://prometheus.io/docs/prometheus/latest/disabled_features/ - enableFeatures: [] - # - exemplar-storage - - ## Image of Prometheus. - ## - image: - repository: rancher/mirrored-prometheus-prometheus - tag: v2.53.1 - sha: "" - - ## Tolerations for use with node taints - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - ## - tolerations: [] - # - key: "key" - # operator: "Equal" - # value: "value" - # effect: "NoSchedule" - - ## If specified, the pod's topology spread constraints. - ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ - ## - topologySpreadConstraints: [] - # - maxSkew: 1 - # topologyKey: topology.kubernetes.io/zone - # whenUnsatisfiable: DoNotSchedule - # labelSelector: - # matchLabels: - # app: prometheus - - ## Alertmanagers to which alerts will be sent - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#alertmanagerendpoints - ## - ## Default configuration will connect to the alertmanager deployed as part of this release - ## - alertingEndpoints: [] - # - name: "" - # namespace: "" - # port: http - # scheme: http - # pathPrefix: "" - # tlsConfig: {} - # bearerTokenFile: "" - # apiVersion: v2 - - ## External labels to add to any time series or alerts when communicating with external systems - ## - externalLabels: {} - - ## enable --web.enable-remote-write-receiver flag on prometheus-server - ## - enableRemoteWriteReceiver: false - - ## Name of the external label used to denote replica name - ## - replicaExternalLabelName: "" - - ## If true, the Operator won't add the external label used to denote replica name - ## - replicaExternalLabelNameClear: false - - ## Name of the external label used to denote Prometheus instance name - ## - prometheusExternalLabelName: "" - - ## If true, the Operator won't add the external label used to denote Prometheus instance name - ## - prometheusExternalLabelNameClear: false - - ## External URL at which Prometheus will be reachable. - ## - externalUrl: "" - - ## Define which Nodes the Pods are scheduled on. - ## ref: https://kubernetes.io/docs/user-guide/node-selection/ - ## - nodeSelector: {} - - ## Secrets is a list of Secrets in the same namespace as the Prometheus object, which shall be mounted into the Prometheus Pods. - ## The Secrets are mounted into /etc/prometheus/secrets/. Secrets changes after initial creation of a Prometheus object are not - ## reflected in the running Pods. To change the secrets mounted into the Prometheus Pods, the object must be deleted and recreated - ## with the new list of secrets. - ## - secrets: [] - - ## ConfigMaps is a list of ConfigMaps in the same namespace as the Prometheus object, which shall be mounted into the Prometheus Pods. - ## The ConfigMaps are mounted into /etc/prometheus/configmaps/. - ## - configMaps: [] - - ## QuerySpec defines the query command line flags when starting Prometheus. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#queryspec - ## - query: {} - - ## If nil, select own namespace. Namespaces to be selected for PrometheusRules discovery. - ruleNamespaceSelector: {} - ## Example which selects PrometheusRules in namespaces with label "prometheus" set to "somelabel" - # ruleNamespaceSelector: - # matchLabels: - # prometheus: somelabel - - ## If true, a nil or {} value for prometheus.prometheusSpec.ruleSelector will cause the - ## prometheus resource to be created with selectors based on values in the helm deployment, - ## which will also match the PrometheusRule resources created - ## - ruleSelectorNilUsesHelmValues: false - - ## PrometheusRules to be selected for target discovery. - ## If {}, select all PrometheusRules - ## - ruleSelector: {} - ## Example which select all PrometheusRules resources - ## with label "prometheus" with values any of "example-rules" or "example-rules-2" - # ruleSelector: - # matchExpressions: - # - key: prometheus - # operator: In - # values: - # - example-rules - # - example-rules-2 - # - ## Example which select all PrometheusRules resources with label "role" set to "example-rules" - # ruleSelector: - # matchLabels: - # role: example-rules - - ## If true, a nil or {} value for prometheus.prometheusSpec.serviceMonitorSelector will cause the - ## prometheus resource to be created with selectors based on values in the helm deployment, - ## which will also match the servicemonitors created - ## - serviceMonitorSelectorNilUsesHelmValues: false - - ## ServiceMonitors to be selected for target discovery. - ## If {}, select all ServiceMonitors - ## - serviceMonitorSelector: {} - ## Example which selects ServiceMonitors with label "prometheus" set to "somelabel" - # serviceMonitorSelector: - # matchLabels: - # prometheus: somelabel - - ## Namespaces to be selected for ServiceMonitor discovery. - ## - serviceMonitorNamespaceSelector: {} - ## Example which selects ServiceMonitors in namespaces with label "prometheus" set to "somelabel" - # serviceMonitorNamespaceSelector: - # matchLabels: - # prometheus: somelabel - - ## If true, a nil or {} value for prometheus.prometheusSpec.podMonitorSelector will cause the - ## prometheus resource to be created with selectors based on values in the helm deployment, - ## which will also match the podmonitors created - ## - podMonitorSelectorNilUsesHelmValues: false - - ## PodMonitors to be selected for target discovery. - ## If {}, select all PodMonitors - ## - podMonitorSelector: {} - ## Example which selects PodMonitors with label "prometheus" set to "somelabel" - # podMonitorSelector: - # matchLabels: - # prometheus: somelabel - - ## If nil, select own namespace. Namespaces to be selected for PodMonitor discovery. - podMonitorNamespaceSelector: {} - ## Example which selects PodMonitor in namespaces with label "prometheus" set to "somelabel" - # podMonitorNamespaceSelector: - # matchLabels: - # prometheus: somelabel - - ## If true, a nil or {} value for prometheus.prometheusSpec.probeSelector will cause the - ## prometheus resource to be created with selectors based on values in the helm deployment, - ## which will also match the probes created - ## - probeSelectorNilUsesHelmValues: true - - ## Probes to be selected for target discovery. - ## If {}, select all Probes - ## - probeSelector: {} - ## Example which selects Probes with label "prometheus" set to "somelabel" - # probeSelector: - # matchLabels: - # prometheus: somelabel - - ## If nil, select own namespace. Namespaces to be selected for Probe discovery. - probeNamespaceSelector: {} - ## Example which selects Probe in namespaces with label "prometheus" set to "somelabel" - # probeNamespaceSelector: - # matchLabels: - # prometheus: somelabel - - ## If true, a nil or {} value for prometheus.prometheusSpec.scrapeConfigSelector will cause the - ## prometheus resource to be created with selectors based on values in the helm deployment, - ## which will also match the scrapeConfigs created - ## - scrapeConfigSelectorNilUsesHelmValues: true - - ## scrapeConfigs to be selected for target discovery. - ## If {}, select all scrapeConfigs - ## - scrapeConfigSelector: {} - ## Example which selects scrapeConfigs with label "prometheus" set to "somelabel" - # scrapeConfigSelector: - # matchLabels: - # prometheus: somelabel - - ## If nil, select own namespace. Namespaces to be selected for scrapeConfig discovery. - scrapeConfigNamespaceSelector: {} - ## Example which selects scrapeConfig in namespaces with label "prometheus" set to "somelabel" - # scrapeConfigNamespaceSelector: - # matchLabels: - # prometheus: somelabel - - ## How long to retain metrics - ## - retention: 10d - - ## Maximum size of metrics - ## - retentionSize: "" - - ## Allow out-of-order/out-of-bounds samples ingested into Prometheus for a specified duration - ## See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#tsdb - tsdb: - outOfOrderTimeWindow: 0s - - ## Enable compression of the write-ahead log using Snappy. - ## - walCompression: true - - ## If true, the Operator won't process any Prometheus configuration changes - ## - paused: false - - ## Number of replicas of each shard to deploy for a Prometheus deployment. - ## Number of replicas multiplied by shards is the total number of Pods created. - ## - replicas: 1 - - ## EXPERIMENTAL: Number of shards to distribute targets onto. - ## Number of replicas multiplied by shards is the total number of Pods created. - ## Note that scaling down shards will not reshard data onto remaining instances, it must be manually moved. - ## Increasing shards will not reshard data either but it will continue to be available from the same instances. - ## To query globally use Thanos sidecar and Thanos querier or remote write data to a central location. - ## Sharding is done on the content of the `__address__` target meta-label. - ## - shards: 1 - - ## Log level for Prometheus be configured in - ## - logLevel: info - - ## Log format for Prometheus be configured in - ## - logFormat: logfmt - - ## Prefix used to register routes, overriding externalUrl route. - ## Useful for proxies that rewrite URLs. - ## - routePrefix: / - - ## Standard object's metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata - ## Metadata Labels and Annotations gets propagated to the prometheus pods. - ## - podMetadata: {} - # labels: - # app: prometheus - # k8s-app: prometheus - - ## Pod anti-affinity can prevent the scheduler from placing Prometheus replicas on the same node. - ## The default value "soft" means that the scheduler should *prefer* to not schedule two replica pods onto the same node but no guarantee is provided. - ## The value "hard" means that the scheduler is *required* to not schedule two replica pods onto the same node. - ## The value "" will disable pod anti-affinity so that no anti-affinity rules will be configured. - podAntiAffinity: "" - - ## If anti-affinity is enabled sets the topologyKey to use for anti-affinity. - ## This can be changed to, for example, failure-domain.beta.kubernetes.io/zone - ## - podAntiAffinityTopologyKey: kubernetes.io/hostname - - ## Assign custom affinity rules to the prometheus instance - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - ## - affinity: {} - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/e2e-az-name - # operator: In - # values: - # - e2e-az1 - # - e2e-az2 - - ## The remote_read spec configuration for Prometheus. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#remotereadspec - remoteRead: [] - # - url: http://remote1/read - ## additionalRemoteRead is appended to remoteRead - additionalRemoteRead: [] - - ## The remote_write spec configuration for Prometheus. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#remotewritespec - remoteWrite: [] - # - url: http://remote1/push - ## additionalRemoteWrite is appended to remoteWrite - additionalRemoteWrite: [] - - ## Enable/Disable Grafana dashboards provisioning for prometheus remote write feature - remoteWriteDashboards: false - - ## Resource limits & requests - ## - resources: - limits: - memory: 3000Mi - cpu: 1000m - requests: - memory: 750Mi - cpu: 750m - - ## Prometheus StorageSpec for persistent data - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/storage.md - ## - storageSpec: {} - ## Using PersistentVolumeClaim - ## - # volumeClaimTemplate: - # spec: - # storageClassName: gluster - # accessModes: ["ReadWriteOnce"] - # resources: - # requests: - # storage: 50Gi - # selector: {} - - ## Using tmpfs volume - ## - # emptyDir: - # medium: Memory - - # Additional volumes on the output StatefulSet definition. - volumes: - - name: nginx-home - emptyDir: {} - - name: prometheus-nginx - configMap: - name: prometheus-nginx-proxy-config - defaultMode: 438 - - # Additional VolumeMounts on the output StatefulSet definition. - volumeMounts: [] - - ## AdditionalScrapeConfigs allows specifying additional Prometheus scrape configurations. Scrape configurations - ## are appended to the configurations generated by the Prometheus Operator. Job configurations must have the form - ## as specified in the official Prometheus documentation: - ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config. As scrape configs are - ## appended, the user is responsible to make sure it is valid. Note that using this feature may expose the possibility - ## to break upgrades of Prometheus. It is advised to review Prometheus release notes to ensure that no incompatible - ## scrape configs are going to break Prometheus after the upgrade. - ## AdditionalScrapeConfigs can be defined as a list or as a templated string. - ## - ## The scrape configuration example below will find master nodes, provided they have the name .*mst.*, relabel the - ## port to 2379 and allow etcd scraping provided it is running on all Kubernetes master nodes - ## - additionalScrapeConfigs: [] - # - job_name: kube-etcd - # kubernetes_sd_configs: - # - role: node - # scheme: https - # tls_config: - # ca_file: /etc/prometheus/secrets/etcd-client-cert/etcd-ca - # cert_file: /etc/prometheus/secrets/etcd-client-cert/etcd-client - # key_file: /etc/prometheus/secrets/etcd-client-cert/etcd-client-key - # relabel_configs: - # - action: labelmap - # regex: __meta_kubernetes_node_label_(.+) - # - source_labels: [__address__] - # action: replace - # targetLabel: __address__ - # regex: ([^:;]+):(\d+) - # replacement: ${1}:2379 - # - source_labels: [__meta_kubernetes_node_name] - # action: keep - # regex: .*mst.* - # - source_labels: [__meta_kubernetes_node_name] - # action: replace - # targetLabel: node - # regex: (.*) - # replacement: ${1} - # metric_relabel_configs: - # - regex: (kubernetes_io_hostname|failure_domain_beta_kubernetes_io_region|beta_kubernetes_io_os|beta_kubernetes_io_arch|beta_kubernetes_io_instance_type|failure_domain_beta_kubernetes_io_zone) - # action: labeldrop - # - ## If scrape config contains a repetitive section, you may want to use a template. - ## In the following example, you can see how to define `gce_sd_configs` for multiple zones - # additionalScrapeConfigs: | - # - job_name: "node-exporter" - # gce_sd_configs: - # {{range $zone := .Values.gcp_zones}} - # - project: "project1" - # zone: "{{$zone}}" - # port: 9100 - # {{end}} - # relabel_configs: - # ... - - - ## If additional scrape configurations are already deployed in a single secret file you can use this section. - ## Expected values are the secret name and key - ## Cannot be used with additionalScrapeConfigs - additionalScrapeConfigsSecret: {} - # enabled: false - # name: - # key: - - ## additionalPrometheusSecretsAnnotations allows to add annotations to the kubernetes secret. This can be useful - ## when deploying via spinnaker to disable versioning on the secret, strategy.spinnaker.io/versioned: 'false' - additionalPrometheusSecretsAnnotations: {} - - ## AdditionalAlertManagerConfigs allows for manual configuration of alertmanager jobs in the form as specified - ## in the official Prometheus documentation https://prometheus.io/docs/prometheus/latest/configuration/configuration/#. - ## AlertManager configurations specified are appended to the configurations generated by the Prometheus Operator. - ## As AlertManager configs are appended, the user is responsible to make sure it is valid. Note that using this - ## feature may expose the possibility to break upgrades of Prometheus. It is advised to review Prometheus release - ## notes to ensure that no incompatible AlertManager configs are going to break Prometheus after the upgrade. - ## - additionalAlertManagerConfigs: [] - # - consul_sd_configs: - # - server: consul.dev.test:8500 - # scheme: http - # datacenter: dev - # tag_separator: ',' - # services: - # - metrics-prometheus-alertmanager - - ## If additional alertmanager configurations are already deployed in a single secret, or you want to manage - ## them separately from the helm deployment, you can use this section. - ## Expected values are the secret name and key - ## Cannot be used with additionalAlertManagerConfigs - additionalAlertManagerConfigsSecret: {} - # name: - # key: - # optional: false - - ## AdditionalAlertRelabelConfigs allows specifying Prometheus alert relabel configurations. Alert relabel configurations specified are appended - ## to the configurations generated by the Prometheus Operator. Alert relabel configurations specified must have the form as specified in the - ## official Prometheus documentation: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs. - ## As alert relabel configs are appended, the user is responsible to make sure it is valid. Note that using this feature may expose the - ## possibility to break upgrades of Prometheus. It is advised to review Prometheus release notes to ensure that no incompatible alert relabel - ## configs are going to break Prometheus after the upgrade. - ## - additionalAlertRelabelConfigs: [] - # - separator: ; - # regex: prometheus_replica - # replacement: $1 - # action: labeldrop - - ## If additional alert relabel configurations are already deployed in a single secret, or you want to manage - ## them separately from the helm deployment, you can use this section. - ## Expected values are the secret name and key - ## Cannot be used with additionalAlertRelabelConfigs - additionalAlertRelabelConfigsSecret: {} - # name: - # key: - - ## SecurityContext holds pod-level security attributes and common container settings. - ## This defaults to non root user with uid 1000 and gid 2000. - ## https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md - ## - securityContext: - runAsGroup: 2000 - runAsNonRoot: true - runAsUser: 1000 - fsGroup: 2000 - seccompProfile: - type: RuntimeDefault - - ## Priority class assigned to the Pods - ## - priorityClassName: "" - - ## Thanos configuration allows configuring various aspects of a Prometheus server in a Thanos environment. - ## This section is experimental, it may change significantly without deprecation notice in any release. - ## This is experimental and may change significantly without backward compatibility in any release. - ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#thanosspec - ## - thanos: {} - # secretProviderClass: - # provider: gcp - # parameters: - # secrets: | - # - resourceName: "projects/$PROJECT_ID/secrets/testsecret/versions/latest" - # fileName: "objstore.yaml" - ## ObjectStorageConfig configures object storage in Thanos. - # objectStorageConfig: - # # use existing secret, if configured, objectStorageConfig.secret will not be used - # existingSecret: {} - # # name: "" - # # key: "" - # # will render objectStorageConfig secret data and configure it to be used by Thanos custom resource, - # # ignored when prometheusspec.thanos.objectStorageConfig.existingSecret is set - # # https://thanos.io/tip/thanos/storage.md/#s3 - # secret: {} - # # type: S3 - # # config: - # # bucket: "" - # # endpoint: "" - # # region: "" - # # access_key: "" - # # secret_key: "" - - proxy: - image: - repository: rancher/mirrored-library-nginx - tag: 1.24.0-alpine - - ## Containers allows injecting additional containers. This is meant to allow adding an authentication proxy to a Prometheus pod. - ## if using proxy extraContainer update targetPort with proxy container port - containers: | - - name: prometheus-proxy - args: - - nginx - - -g - - daemon off; - - -c - - /nginx/nginx.conf - image: "{{ template "system_default_registry" . }}{{ .Values.prometheus.prometheusSpec.proxy.image.repository }}:{{ .Values.prometheus.prometheusSpec.proxy.image.tag }}" - ports: - - containerPort: 8081 - name: nginx-http - protocol: TCP - volumeMounts: - - mountPath: /nginx - name: prometheus-nginx - - mountPath: /var/cache/nginx - name: nginx-home - securityContext: - runAsUser: 101 - runAsGroup: 101 - - ## InitContainers allows injecting additional initContainers. This is meant to allow doing some changes - ## (permissions, dir tree) on mounted volumes before starting prometheus - initContainers: [] - - ## PortName to use for Prometheus. - ## - portName: "http-web" - - ## ArbitraryFSAccessThroughSMs configures whether configuration based on a service monitor can access arbitrary files - ## on the file system of the Prometheus container e.g. bearer token files. - arbitraryFSAccessThroughSMs: false - - ## OverrideHonorLabels if set to true overrides all user configured honor_labels. If HonorLabels is set in ServiceMonitor - ## or PodMonitor to true, this overrides honor_labels to false. - overrideHonorLabels: false - - ## OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs. - overrideHonorTimestamps: false - - ## When ignoreNamespaceSelectors is set to true, namespaceSelector from all PodMonitor, ServiceMonitor and Probe objects will be ignored, - ## they will only discover targets within the namespace of the PodMonitor, ServiceMonitor and Probe object, - ## and servicemonitors will be installed in the default service namespace. - ## Defaults to false. - ignoreNamespaceSelectors: true - - ## EnforcedNamespaceLabel enforces adding a namespace label of origin for each alert and metric that is user created. - ## The label value will always be the namespace of the object that is being created. - ## Disabled by default - enforcedNamespaceLabel: "" - - ## PrometheusRulesExcludedFromEnforce - list of prometheus rules to be excluded from enforcing of adding namespace labels. - ## Works only if enforcedNamespaceLabel set to true. Make sure both ruleNamespace and ruleName are set for each pair - ## Deprecated, use `excludedFromEnforcement` instead - prometheusRulesExcludedFromEnforce: [] - - ## ExcludedFromEnforcement - list of object references to PodMonitor, ServiceMonitor, Probe and PrometheusRule objects - ## to be excluded from enforcing a namespace label of origin. - ## Works only if enforcedNamespaceLabel set to true. - ## See https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#objectreference - excludedFromEnforcement: [] - - ## QueryLogFile specifies the file to which PromQL queries are logged. Note that this location must be writable, - ## and can be persisted using an attached volume. Alternatively, the location can be set to a stdout location such - ## as /dev/stdout to log querie information to the default Prometheus log stream. This is only available in versions - ## of Prometheus >= 2.16.0. For more details, see the Prometheus docs (https://prometheus.io/docs/guides/query-log/) - queryLogFile: false - - # Use to set global sample_limit for Prometheus. This act as default SampleLimit for ServiceMonitor or/and PodMonitor. - # Set to 'false' to disable global sample_limit. or set to a number to override the default value. - sampleLimit: false - - # EnforcedKeepDroppedTargetsLimit defines on the number of targets dropped by relabeling that will be kept in memory. - # The value overrides any spec.keepDroppedTargets set by ServiceMonitor, PodMonitor, Probe objects unless spec.keepDroppedTargets - # is greater than zero and less than spec.enforcedKeepDroppedTargets. 0 means no limit. - enforcedKeepDroppedTargets: 0 - - ## EnforcedSampleLimit defines global limit on number of scraped samples that will be accepted. This overrides any SampleLimit - ## set per ServiceMonitor or/and PodMonitor. It is meant to be used by admins to enforce the SampleLimit to keep overall - ## number of samples/series under the desired limit. Note that if SampleLimit is lower that value will be taken instead. - enforcedSampleLimit: false - - ## EnforcedTargetLimit defines a global limit on the number of scraped targets. This overrides any TargetLimit set - ## per ServiceMonitor or/and PodMonitor. It is meant to be used by admins to enforce the TargetLimit to keep the overall - ## number of targets under the desired limit. Note that if TargetLimit is lower, that value will be taken instead, except - ## if either value is zero, in which case the non-zero value will be used. If both values are zero, no limit is enforced. - enforcedTargetLimit: false - - - ## Per-scrape limit on number of labels that will be accepted for a sample. If more than this number of labels are present - ## post metric-relabeling, the entire scrape will be treated as failed. 0 means no limit. Only valid in Prometheus versions - ## 2.27.0 and newer. - enforcedLabelLimit: false - - ## Per-scrape limit on length of labels name that will be accepted for a sample. If a label name is longer than this number - ## post metric-relabeling, the entire scrape will be treated as failed. 0 means no limit. Only valid in Prometheus versions - ## 2.27.0 and newer. - enforcedLabelNameLengthLimit: false - - ## Per-scrape limit on length of labels value that will be accepted for a sample. If a label value is longer than this - ## number post metric-relabeling, the entire scrape will be treated as failed. 0 means no limit. Only valid in Prometheus - ## versions 2.27.0 and newer. - enforcedLabelValueLengthLimit: false - - ## AllowOverlappingBlocks enables vertical compaction and vertical query merge in Prometheus. This is still experimental - ## in Prometheus so it may change in any upcoming release. - allowOverlappingBlocks: false - - ## Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to - ## be considered available. Defaults to 0 (pod will be considered available as soon as it is ready). - minReadySeconds: 0 - - # Required for use in managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico), - # because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working - # Use the host's network namespace if true. Make sure to understand the security implications if you want to enable it. - # When hostNetwork is enabled, this will set dnsPolicy to ClusterFirstWithHostNet automatically. - hostNetwork: false - - # HostAlias holds the mapping between IP and hostnames that will be injected - # as an entry in the pod’s hosts file. - hostAliases: [] - # - ip: 10.10.0.100 - # hostnames: - # - a1.app.local - # - b1.app.local - - ## TracingConfig configures tracing in Prometheus. - ## See https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#prometheustracingconfig - tracingConfig: {} - - ## Additional configuration which is not covered by the properties above. (passed through tpl) - additionalConfig: {} - - ## Additional configuration which is not covered by the properties above. - ## Useful, if you need advanced templating inside alertmanagerSpec. - ## Otherwise, use prometheus.prometheusSpec.additionalConfig (passed through tpl) - additionalConfigString: "" - - ## Defines the maximum time that the `prometheus` container's startup probe - ## will wait before being considered failed. The startup probe will return - ## success after the WAL replay is complete. If set, the value should be - ## greater than 60 (seconds). Otherwise it will be equal to 900 seconds (15 - ## minutes). - maximumStartupDurationSeconds: 0 - - additionalRulesForClusterRole: [] - # - apiGroups: [ "" ] - # resources: - # - nodes/proxy - # verbs: [ "get", "list", "watch" ] - - additionalServiceMonitors: [] - ## Name of the ServiceMonitor to create - ## - # - name: "" - - ## Additional labels to set used for the ServiceMonitorSelector. Together with standard labels from - ## the chart - ## - # additionalLabels: {} - - ## Service label for use in assembling a job name of the form

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

FLzYR`h`hQ7=3i}-|4iG&m_#2hTqNr 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

&Pi-gL#4EBpvFXqc_!I zP^e`uXrXyhX0#yYR?cM6>SpbS0PrXBnk7=CaTdaky}DU#aJAs>f)!k*J_&N=T39Pb zpFc`Y9Rc#UzOEY7LX2lZ7A!ptD7e3$6Y}S!6PeoseYjWtzyM{(XfIDz8T0YVPG!OF zSwT)xiM7%1d7@7zM^Adprajr3>bpXR7h zQm`4^D7-5h-lvEX&P@W8mJ6B5+46c}6y^&llrG@D50ID^GCfwlC8D4y%>2c+HkF|I zB#p{B@-4k(*)@cW$RduAxEVYclGudSfWd1i$xPer)`KA1Ikol;F#7n~vH^E^HVtNFs}Zsf83+UCbTuROXbo!qP?gl+5^z?#7gA zR!>@%c=bb26d?7-%&NW?J?1-5>7Xhsx|GA;z%rh{d)2L4_h!BfO(i*B-OXT3I8*-@ zI0jbhwzvaogp%3Fl|c4%*}UA-HOO+7o*9wWG=Z%?9mwxpCD7x#)CBsdZN?`M_|EF6A_8!|-X6!!N~%yp!7eClJYBNv7UO4Zqpx>fvDbv36F3 zvuSsR>6^vDLAf<*l3gwZk%e7?h;F=yqiiQm=Mz$lUBqCUgk*XOmv*ZTZD-&h#J@l> z-bF?e1{fgVyD=+Zbe2xQaQEb_m@%>d`$F&Q5rojrApUs7C3Cr_Ed#3;AboeBx?{h~ zov%e=@5W7j!)XH-1(BpXOJ`tKPxSr{3X!PBiYzdv3v-?Sk2mT4U$UUQP!n=a6c@9M z)&6FU>p?R;-7VIQ2~-e`h z_lzDKdPnfLqfNz@h!Ys`%5W^kY74&UNVbeU8*gi^Iq67S;kFVOR1i#Wl{JN7oM1|5 zS8G5`fnZ2$3P@;{ltxOjF^JH(PYgF|kCb=i!tI=k(&-ShZDgh&FX+woD2-8j#@|;P zi^1kK-K4{c6;6Cs$P#W2GyKMB8^Ka^PPw%c7hN092G>W?+?z+Ivbg1Gip9ub0On%e zN z0A`4jD6`D4eM}PoodxY!80vv$;F-DRy1v0(USuB@j3HGG@B(J!^_995S2De+spB;a z0hjcE9&>Wy{&DNgb*;|19!VgAKlC%c4VYd|KV9FkhwW(&G_#UPnX*~Iu%0|zBe+&M zU1E>`yJu#5Q*LH`TXuSD!4>n-oZRn)qMEBI_+tP2m3$|)bGUr;VF5wf@xo~Nka(H$ zsde0T983McZ0vAl5~vv=+>y7y^j`IM+-a7{Tbj8f()JnMti9_;Zh!0;0I*#?g9r|^ zIkX$43-U87B<7Qbvs!5Y?n=fKTyjC)a`6g(-#&#m=E{De`66Q@43qzQ{Ie8{Bw496 zD@OiURG}v?kdMPefM9D&4_kYwo6M{Ukt*`l*;i*T+Aq|lu%0EVYy{K#YQJco+b_h- z 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 wZ&B$&gFOY|6&uQc0D#x~9Ug80I1&LfX3Ur|Dc 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

FSzE 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

6l#XaB@yw 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

|gmN!Zk_=uuGbcBq7v9 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

NT|dzqWucJ2%) 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 z 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�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�# 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

mt`iC8;vrZVrdiGp94Zxbo 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 + echo "Applying CRDs..."; + mkdir -p /etc/crd; + base64 -d /etc/config/crd-manifest.tgz.b64 | tar -xzv -C /etc/crd; + kubectl replace -Rf /etc/crd || kubectl create -Rf /etc/crd; + echo "Done!" + volumeMounts: + - name: crd-manifest + readOnly: true + mountPath: /etc/config + restartPolicy: OnFailure + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} + {{- if .Values.nodeSelector }} + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + {{- if .Values.tolerations }} + {{- toYaml .Values.tolerations | nindent 8 }} + {{- end }} + volumes: + - name: crd-manifest + configMap: + name: {{ .Chart.Name }}-manifest +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Chart.Name }}-delete + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed +spec: + template: + metadata: + name: {{ .Chart.Name }}-delete + labels: + app: {{ .Chart.Name }} + spec: + serviceAccountName: {{ .Chart.Name }}-manager + securityContext: + runAsNonRoot: false + runAsUser: 0 + containers: + - name: delete-crds + image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - > + echo "Deleting CRDs..."; + mkdir -p /etc/crd; + base64 -d /etc/config/crd-manifest.tgz.b64 | tar -xzv -C /etc/crd; + kubectl delete --ignore-not-found=true -Rf /etc/crd; + volumeMounts: + - name: crd-manifest + readOnly: true + mountPath: /etc/config + restartPolicy: OnFailure + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} + {{- if .Values.nodeSelector }} + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + {{- if .Values.tolerations }} + {{- toYaml .Values.tolerations | nindent 8 }} + {{- end }} + volumes: + - name: crd-manifest + configMap: + name: {{ .Chart.Name }}-manifest diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/manifest.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/manifest.yaml new file mode 100644 index 0000000000..8dc9dfb447 --- /dev/null +++ b/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/manifest.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Chart.Name }}-manifest + namespace: {{ .Release.Namespace }} +data: + crd-manifest.tgz.b64: + {{- .Files.Get "files/crd-manifest.tgz" | b64enc | indent 4 }} diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/rbac.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/rbac.yaml new file mode 100644 index 0000000000..a4d498b0fa --- /dev/null +++ b/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/rbac.yaml @@ -0,0 +1,76 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Chart.Name }}-manager + labels: + app: {{ .Chart.Name }}-manager +rules: +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: ['create', 'get', 'patch', 'delete', 'update', 'list'] +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ .Chart.Name }}-manager +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Chart.Name }}-manager + labels: + app: {{ .Chart.Name }}-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Chart.Name }}-manager +subjects: +- kind: ServiceAccount + name: {{ .Chart.Name }}-manager + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Chart.Name }}-manager + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }}-manager +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ .Chart.Name }}-manager + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }}-manager +spec: + privileged: false + allowPrivilegeEscalation: false + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'configMap' + - 'secret' +{{- end }} diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/validate-psp-install.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/values.yaml b/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/values.yaml new file mode 100644 index 0000000000..99e63600c4 --- /dev/null +++ b/charts/rancher-monitoring-crd/105.1.0-rc.2+up61.3.2/values.yaml @@ -0,0 +1,17 @@ +# Default values for rancher-monitoring-crd. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + +image: + repository: rancher/shell + tag: v0.2.1 + +nodeSelector: {} + +tolerations: [] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/.editorconfig b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/.editorconfig new file mode 100644 index 0000000000..f5ee2f4610 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[files/dashboards/*.json] +indent_size = 2 +indent_style = space \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/.helmignore new file mode 100644 index 0000000000..9bdbec92b4 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/.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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# helm/charts +OWNERS +hack/ +ci/ +kube-prometheus-*.tgz + +unittests/ +files/dashboards/ diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/CHANGELOG.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/CHANGELOG.md new file mode 100644 index 0000000000..8178169b91 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/CHANGELOG.md @@ -0,0 +1,47 @@ +# Changelog +All notable changes from the upstream Prometheus Operator chart will be added to this file. + +## [Package Version 00] - 2020-07-19 +### Added +- Added [Prometheus Adapter](https://github.com/helm/charts/tree/master/stable/prometheus-adapter) as a dependency to the upstream Prometheus Operator chart to allow users to expose custom metrics from the default Prometheus instance deployed by this chart +- Remove `prometheus-operator/cleanup-crds.yaml` and `prometheus-operator/crds.yaml` from the Prometheus Operator upstream chart in favor of just using the CRD directory to install the CRDs. +- Added support for `rkeControllerManager`, `rkeScheduler`, `rkeProxy`, and `rkeEtcd` PushProx exporters for monitoring k8s components within RKE clusters +- Added support for a `k3sServer` PushProx exporter that monitors k3s server components (`kubeControllerManager`, `kubeScheduler`, and `kubeProxy`) within k3s clusters +- Added support for `kubeAdmControllerManager`, `kubeAdmScheduler`, `kubeAdmProxy`, and `kubeAdmEtcd` PushProx exporters for monitoring k8s components within kubeAdm clusters +- Added support for `rke2ControllerManager`, `rke2Scheduler`, `rke2Proxy`, and `rke2Etcd` PushProx exporters for monitoring k8s components within rke2 clusters +- Exposed `prometheus.prometheusSpec.ignoreNamespaceSelectors` on values.yaml and set it to `false` by default. This value instructs the default Prometheus server deployed with this chart to ignore the `namespaceSelector` field within any created ServiceMonitor or PodMonitor CRs that it selects. This prevents ServiceMonitors and PodMonitors from configuring the Prometheus scrape configuration to monitor resources outside the namespace that they are deployed in; if a user needs to have one ServiceMonitor / PodMonitor monitor resources within several namespaces (such as the resources that are used to monitor Istio in a default installation), they should not enable this option since it would require them to create one ServiceMonitor / PodMonitor CR per namespace that they would like to monitor. Relevant fields were also updated in the default README.md. +- Added `grafana.sidecar.dashboards.searchNamespace` to `values.yaml` with a default value of `cattle-dashboards`. The namespace provided should contain all ConfigMaps with the label `grafana_dashboard` and will be searched by the Grafana Dashboards sidecar for updates. The namespace specified is also created along with this deployment. All default dashboard ConfigMaps have been relocated from the deployment namespace to the namespace specified +- Added `monitoring-admin`, `monitoring-edit`, and `monitoring-view` default `ClusterRoles` to allow admins to assign roles to users to interact with Prometheus Operator CRs. These can be enabled by setting `.Values.global.rbac.userRoles.create` (default: `true`). In a typical RBAC setup, you might want to use a `ClusterRoleBinding` to bind these roles to a Subject to allow them to set up or view `ServiceMonitors` / `PodMonitors` / `PrometheusRules` and view `Prometheus` or `Alertmanager` CRs across the cluster. If `.Values.global.rbac.userRoles.aggregateRolesForRBAC` is enabled, these ClusterRoles will aggregate into the respective default ClusterRoles provided by Kubernetes +- Added `monitoring-config-admin`, `monitoring-config-edit` and `monitoring-config-view` default `Roles` to allow admins to assign roles to users to be able to edit / view `Secrets` and `ConfigMaps` within the `cattle-monitoring-system` namespace. These can be enabled by setting `.Values.global.rbac.userRoles.create` (default: `true`). In a typical RBAC setup, you might want to use a `RoleBinding` to bind these roles to a Subject within the `cattle-monitoring-system` namespace to allow them to modify Secrets / ConfigMaps tied to the deployment, such as your Alertmanager Config Secret. +- Added `monitoring-dashboard-admin`, `monitoring-dashboard-edit` and `monitoring-dashboard-view` default `Roles` to allow admins to assign roles to users to be able to edit / view `ConfigMaps` within the `cattle-dashboards` namespace. These can be enabled by setting `.Values.global.rbac.userRoles.create` (default: `true`) and deploying Grafana as part of this chart. In a typical RBAC setup, you might want to use a `RoleBinding` to bind these roles to a Subject within the `cattle-dashboards` namespace to allow them to create / modify ConfigMaps that contain the JSON used to persist Grafana Dashboards on the cluster. +- Added default resource limits for `Prometheus Operator`, `Prometheus`, `AlertManager`, `Grafana`, `kube-state-metrics`, `node-exporter` +- Added a default template `rancher_defaults.tmpl` to AlertManager that Rancher will offer to users in order to help configure the way alerts are rendered on a notifier. Also updated the default template deployed with this chart to reference that template and added an example of a Slack config using this template as a comment in the `values.yaml`. +- Added support for private registries via introducing a new field for `global.cattle.systemDefaultRegistry` that, if supplied, will automatically be prepended onto every image used by the chart. +- Added a default `nginx` proxy container deployed with Grafana whose config is set in the `ConfigMap` located in `charts/grafana/templates/nginx-config.yaml`. The purpose of this container is to make it possible to view Grafana's UI through a proxy that has a subpath (e.g. Rancher's proxy). This proxy container is set to listen on port `8080` (with a `portName` of `nginx-http` instead of the default `service`), which is also where the Grafana service will now point to, and will forward all requests to the Grafana container listening on the default port `3000`. +- Added a default `nginx` proxy container deployed with Prometheus whose config is set in the `ConfigMap` located in `templates/prometheus/nginx-config.yaml`. The purpose of this container is to make it possible to view Prometheus's UI through a proxy that has a subpath (e.g. Rancher's proxy). This proxy container is set to listen on port `8081` (with a `portName` of `nginx-http` instead of the default `web`), which is also where the Prometheus service will now point to, and will forward all requests to the Prometheus container listening on the default port `9090`. +- Added support for passing CIS Scans in a hardened cluster by introducing a Job that patches the default service account within the `cattle-monitoring-system` and `cattle-dashboards` namespaces on install or upgrade and adding a default allow all `NetworkPolicy` to the `cattle-monitoring-system` and `cattle-dashboards` namespaces. +### Modified +- Updated the chart name from `prometheus-operator` to `rancher-monitoring` and added the `io.rancher.certified: rancher` annotation to `Chart.yaml` +- Modified the default `node-exporter` port from `9100` to `9796` +- Modified the default `nameOverride` to `rancher-monitoring`. This change is necessary as the Prometheus Adapter's default URL (`http://{{ .Values.nameOverride }}-prometheus.{{ .Values.namespaceOverride }}.svc`) is based off of the value used here; if modified, the default Adapter URL must also be modified +- Modified the default `namespaceOverride` to `cattle-monitoring-system`. This change is necessary as the Prometheus Adapter's default URL (`http://{{ .Values.nameOverride }}-prometheus.{{ .Values.namespaceOverride }}.svc`) is based off of the value used here; if modified, the default Adapter URL must also be modified +- Configured some default values for `grafana.service` values and exposed them in the default README.md +- The default namespaces the following ServiceMonitors were changed from the deployment namespace to allow them to continue to monitor metrics when `prometheus.prometheusSpec.ignoreNamespaceSelectors` is enabled: + - `core-dns`: `kube-system` + - `api-server`: `default` + - `kube-controller-manager`: `kube-system` + - `kubelet`: `{{ .Values.kubelet.namespace }}` +- Disabled the following deployments by default (can be enabled if required): + - `AlertManager` + - `kube-controller-manager` metrics exporter + - `kube-etcd` metrics exporter + - `kube-scheduler` metrics exporter + - `kube-proxy` metrics exporter +- Updated default Grafana `deploymentStrategy` to `Recreate` to prevent deployments from being stuck on upgrade if a PV is attached to Grafana +- Modified the default `SelectorNilUsesHelmValues` to default to `false`. As a result, we look for all CRs with any labels in all namespaces by default rather than just the ones tagged with the label `release: rancher-monitoring`. +- Modified the default images used by the `rancher-monitoring` chart to point to Rancher mirrors of the original images from upstream. +- Modified the behavior of the chart to create the Alertmanager Config Secret via a pre-install hook instead of using the normal Helm lifecycle to manage the secret. The benefit of this approach is that all changes to the Config Secret done on a live cluster will never get overridden on a `helm upgrade` since the secret only gets created on a `helm install`. If you would like the secret to be cleaned up on an `helm uninstall`, enable `alertmanager.cleanupOnUninstall`; however, this is disabled by default to prevent the loss of alerting configuration on an uninstall. This secret will never be modified on a `helm upgrade`. +- Modified the default `securityContext` for `Pod` templates across the chart to `{"runAsNonRoot": "true", "runAsUser": "1000"}` and replaced `grafana.rbac.pspUseAppArmor` in favor of `grafana.rbac.pspAnnotations={}` in order to make it possible to deploy this chart on a hardened cluster which does not support Seccomp or AppArmor annotations in PSPs. Users can always choose to specify the annotations they want to use for the PSP directly as part of the values provided. +- Modified `.Values.prometheus.prometheusSpec.containers` to take in a string representing a template that should be rendered by Helm (via `tpl`) instead of allowing a user to provide YAML directly. +- Modified the default Grafana configuration to auto assign users who access Grafana to the Viewer role and enable anonymous access to Grafana dashboards by default. This default works well for a Rancher user who is accessing Grafana via the `kubectl proxy` on the Rancher Dashboard UI since anonymous users who enter via the proxy are authenticated by the k8s API Server, but you can / should modify this behavior if you plan on exposing Grafana in a way that does not require authentication (e.g. as a `NodePort` service). +- Modified the default Grafana configuration to add a default dashboard for Rancher on the Grafana home page. \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/CONTRIBUTING.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/CONTRIBUTING.md new file mode 100644 index 0000000000..f6ce2a3235 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/CONTRIBUTING.md @@ -0,0 +1,12 @@ +# Contributing Guidelines + +## How to contribute to this chart + +1. Fork this repository, develop and test your Chart. +1. Bump the chart version for every change. +1. Ensure PR title has the prefix `[kube-prometheus-stack]` +1. When making changes to rules or dashboards, see the README.md section on how to sync data from upstream repositories +1. Check the `hack/minikube` folder has scripts to set up minikube and components of this chart that will allow all components to be scraped. You can use this configuration when validating your changes. +1. Check for changes of RBAC rules. +1. Check for changes in CRD specs. +1. PR must pass the linter (`helm lint`) diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/Chart.yaml new file mode 100644 index 0000000000..9ed473adfc --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/Chart.yaml @@ -0,0 +1,126 @@ +annotations: + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/prometheus-community/helm-charts + - name: Upstream Project + url: https://github.com/prometheus-operator/kube-prometheus + artifacthub.io/operator: "true" + catalog.cattle.io/auto-install: rancher-monitoring-crd=match + catalog.cattle.io/certified: rancher + catalog.cattle.io/deploys-on-os: windows + catalog.cattle.io/display-name: Monitoring + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/namespace: cattle-monitoring-system + catalog.cattle.io/permits-os: linux,windows + catalog.cattle.io/provides-gvr: monitoring.coreos.com.prometheus/v1 + catalog.cattle.io/rancher-version: '>= 2.9.0-0 < 2.10.0-0' + catalog.cattle.io/release-name: rancher-monitoring + catalog.cattle.io/requests-cpu: 4500m + catalog.cattle.io/requests-memory: 4000Mi + catalog.cattle.io/type: cluster-tool + catalog.cattle.io/ui-component: monitoring + catalog.cattle.io/upstream-version: 57.0.3 +apiVersion: v2 +appVersion: v0.75.1 +dependencies: +- condition: grafana.enabled + name: grafana + repository: file://./charts/grafana +- condition: hardenedKubelet.enabled + name: hardenedKubelet + repository: file://./charts/hardenedKubelet +- condition: hardenedNodeExporter.enabled + name: hardenedNodeExporter + repository: file://./charts/hardenedNodeExporter +- condition: k3sServer.enabled + name: k3sServer + repository: file://./charts/k3sServer +- condition: kubeStateMetrics.enabled + name: kube-state-metrics + repository: file://./charts/kube-state-metrics +- condition: kubeAdmControllerManager.enabled + name: kubeAdmControllerManager + repository: file://./charts/kubeAdmControllerManager +- condition: kubeAdmEtcd.enabled + name: kubeAdmEtcd + repository: file://./charts/kubeAdmEtcd +- condition: kubeAdmProxy.enabled + name: kubeAdmProxy + repository: file://./charts/kubeAdmProxy +- condition: kubeAdmScheduler.enabled + name: kubeAdmScheduler + repository: file://./charts/kubeAdmScheduler +- condition: prometheus-adapter.enabled + name: prometheus-adapter + repository: file://./charts/prometheus-adapter +- condition: nodeExporter.enabled + name: prometheus-node-exporter + repository: file://./charts/prometheus-node-exporter +- condition: rke2ControllerManager.enabled + name: rke2ControllerManager + repository: file://./charts/rke2ControllerManager +- condition: rke2Etcd.enabled + name: rke2Etcd + repository: file://./charts/rke2Etcd +- condition: rke2IngressNginx.enabled + name: rke2IngressNginx + repository: file://./charts/rke2IngressNginx +- condition: rke2Proxy.enabled + name: rke2Proxy + repository: file://./charts/rke2Proxy +- condition: rke2Scheduler.enabled + name: rke2Scheduler + repository: file://./charts/rke2Scheduler +- condition: rkeControllerManager.enabled + name: rkeControllerManager + repository: file://./charts/rkeControllerManager +- condition: rkeEtcd.enabled + name: rkeEtcd + repository: file://./charts/rkeEtcd +- condition: rkeIngressNginx.enabled + name: rkeIngressNginx + repository: file://./charts/rkeIngressNginx +- condition: rkeProxy.enabled + name: rkeProxy + repository: file://./charts/rkeProxy +- condition: rkeScheduler.enabled + name: rkeScheduler + repository: file://./charts/rkeScheduler +- condition: windowsExporter.enabled + name: windowsExporter + repository: file://./charts/windowsExporter +description: kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards, + and Prometheus rules combined with documentation and scripts to provide easy to + operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus + Operator. +home: https://github.com/prometheus-operator/kube-prometheus +icon: file://assets/logos/rancher-monitoring.png +keywords: +- operator +- prometheus +- kube-prometheus +kubeVersion: '>=1.28.0-0' +maintainers: +- email: andrew@quadcorps.co.uk + name: andrewgkew +- email: gianrubio@gmail.com + name: gianrubio +- email: github.gkarthiks@gmail.com + name: gkarthiks +- email: kube-prometheus-stack@sisti.pt + name: GMartinez-Sisti +- email: github@jkroepke.de + name: jkroepke +- email: scott@r6by.com + name: scottrigby +- email: miroslav.hadzhiev@gmail.com + name: Xtigyro +- email: quentin.bisson@gmail.com + name: QuentinBisson +name: rancher-monitoring +sources: +- https://github.com/prometheus-community/helm-charts +- https://github.com/prometheus-operator/kube-prometheus +type: application +version: 105.1.0-rc.2+up61.3.2 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/README.md new file mode 100644 index 0000000000..46f751587e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/README.md @@ -0,0 +1,1140 @@ +# kube-prometheus-stack + +Installs the [kube-prometheus stack](https://github.com/prometheus-operator/kube-prometheus), a collection of Kubernetes manifests, [Grafana](http://grafana.com/) dashboards, and [Prometheus rules](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with [Prometheus](https://prometheus.io/) using the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator). + +See the [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) README for details about components, dashboards, and alerts. + +_Note: This chart was formerly named `prometheus-operator` chart, now renamed to more clearly reflect that it installs the `kube-prometheus` project stack, within which Prometheus Operator is only one component._ + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3+ + +## Get Helm Repository Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Helm Chart + +```console +helm install [RELEASE_NAME] prometheus-community/kube-prometheus-stack +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Dependencies + +By default this chart installs additional, dependent charts: + +- [prometheus-community/kube-state-metrics](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics) +- [prometheus-community/prometheus-node-exporter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-node-exporter) +- [grafana/grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana) + +To disable dependencies during installation, see [multiple releases](#multiple-releases) below. + +_See [helm dependency](https://helm.sh/docs/helm/helm_dependency/) for command documentation._ + +## 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._ + +CRDs created by this chart are not removed by default and should be manually cleaned up: + +```console +kubectl delete crd alertmanagerconfigs.monitoring.coreos.com +kubectl delete crd alertmanagers.monitoring.coreos.com +kubectl delete crd podmonitors.monitoring.coreos.com +kubectl delete crd probes.monitoring.coreos.com +kubectl delete crd prometheusagents.monitoring.coreos.com +kubectl delete crd prometheuses.monitoring.coreos.com +kubectl delete crd prometheusrules.monitoring.coreos.com +kubectl delete crd scrapeconfigs.monitoring.coreos.com +kubectl delete crd servicemonitors.monitoring.coreos.com +kubectl delete crd thanosrulers.monitoring.coreos.com +``` + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] prometheus-community/kube-prometheus-stack +``` + +With Helm v3, CRDs created by this chart are not updated by default and should be manually updated. +Consult also the [Helm Documentation on CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions). + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### 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. + +### From 60.x to 61.x + +This version upgrades Prometheus-Operator to v0.75.0 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.75.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 59.x to 60.x + +This version upgrades the Grafana chart to v8.0.x which introduces Grafana 11. This new major version of Grafana contains some breaking changes described in [Breaking changes in Grafana v11.0](https://grafana.com/docs/grafana/latest/breaking-changes/breaking-changes-v11-0/). + +### From 58.x to 59.x + +This version upgrades Prometheus-Operator to v0.74.0 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.74.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 57.x to 58.x + +This version upgrades Prometheus-Operator to v0.73.0 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.73.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 56.x to 57.x + +This version upgrades Prometheus-Operator to v0.72.0 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.72.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 55.x to 56.x + +This version upgrades Prometheus-Operator to v0.71.0, Prometheus to 2.49.1 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.71.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 54.x to 55.x + +This version upgrades Prometheus-Operator to v0.70.0 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.70.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 53.x to 54.x + +Grafana Helm Chart has bumped to version 7 + +Please note Grafana Helm Chart [changelog](https://github.com/grafana/helm-charts/tree/main/charts/grafana#to-700). + +### From 52.x to 53.x + +This version upgrades Prometheus-Operator to v0.69.1, Prometheus to 2.47.2 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.69.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 51.x to 52.x + +This includes the ability to select between using existing secrets or create new secret objects for various thanos config. The defaults have not changed but if you were setting: + +- `thanosRuler.thanosRulerSpec.alertmanagersConfig` or +- `thanosRuler.thanosRulerSpec.objectStorageConfig` or +- `thanosRuler.thanosRulerSpec.queryConfig` or +- `prometheus.prometheusSpec.thanos.objectStorageConfig` + +you will have to need to set `existingSecret` or `secret` based on your requirement + +For instance, the `thanosRuler.thanosRulerSpec.alertmanagersConfig` used to be configured as follow: + +```yaml +thanosRuler: + thanosRulerSpec: + alertmanagersConfig: + alertmanagers: + - api_version: v2 + http_config: + basic_auth: + username: some_user + password: some_pass + static_configs: + - alertmanager.thanos.io + scheme: http + timeout: 10s +``` + +But it now moved to: + +```yaml +thanosRuler: + thanosRulerSpec: + alertmanagersConfig: + secret: + alertmanagers: + - api_version: v2 + http_config: + basic_auth: + username: some_user + password: some_pass + static_configs: + - alertmanager.thanos.io + scheme: http + timeout: 10s +``` + +or the `thanosRuler.thanosRulerSpec.objectStorageConfig` used to be configured as follow: + +```yaml +thanosRuler: + thanosRulerSpec: + objectStorageConfig: + name: existing-secret-not-created-by-this-chart + key: object-storage-configs.yaml +``` + +But it now moved to: + +```yaml +thanosRuler: + thanosRulerSpec: + objectStorageConfig: + existingSecret: + name: existing-secret-not-created-by-this-chart + key: object-storage-configs.yaml +``` + +### From 50.x to 51.x + +This version upgrades Prometheus-Operator to v0.68.0, Prometheus to 2.47.0 and Thanos to v0.32.2 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 49.x to 50.x + +This version requires Kubernetes 1.19+. + +We do not expect any breaking changes in this version. + +### From 48.x to 49.x + +This version upgrades Prometheus-Operator to v0.67.1, 0, Alertmanager to v0.26.0, Prometheus to 2.46.0 and Thanos to v0.32.0 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.67.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 47.x to 48.x + +This version moved all CRDs into a dedicated sub-chart. No new CRDs are introduced in this version. +See [#3548](https://github.com/prometheus-community/helm-charts/issues/3548) for more context. + +We do not expect any breaking changes in this version. + +### From 46.x to 47.x + +This version upgrades Prometheus-Operator to v0.66.0 with new CRDs (PrometheusAgent and ScrapeConfig). + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.66.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 45.x to 46.x + +This version upgrades Prometheus-Operator to v0.65.1 with new CRDs (PrometheusAgent and ScrapeConfig), Prometheus to v2.44.0 and Thanos to v0.31.0. + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusagents.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 44.x to 45.x + +This version upgrades Prometheus-Operator to v0.63.0, Prometheus to v2.42.0 and Thanos to v0.30.2. + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.63.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 43.x to 44.x + +This version upgrades Prometheus-Operator to v0.62.0, Prometheus to v2.41.0 and Thanos to v0.30.1. + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.62.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +If you have explicitly set `prometheusOperator.admissionWebhooks.failurePolicy`, this value is now always used even when `.prometheusOperator.admissionWebhooks.patch.enabled` is `true` (the default). + +The values for `prometheusOperator.image.tag` & `prometheusOperator.prometheusConfigReloader.image.tag` are now empty by default and the Chart.yaml `appVersion` field is used instead. + +### From 42.x to 43.x + +This version upgrades Prometheus-Operator to v0.61.1, Prometheus to v2.40.5 and Thanos to v0.29.0. + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.61.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 41.x to 42.x + +This includes the overridability of container registry for all containers at the global level using `global.imageRegistry` or per container image. The defaults have not changed but if you were using a custom image, you will have to override the registry of said custom container image before you upgrade. + +For instance, the prometheus-config-reloader used to be configured as follow: + +```yaml + image: + repository: quay.io/prometheus-operator/prometheus-config-reloader + tag: v0.60.1 + sha: "" +``` + +But it now moved to: + +```yaml + image: + registry: quay.io + repository: prometheus-operator/prometheus-config-reloader + tag: v0.60.1 + sha: "" +``` + +### From 40.x to 41.x + +This version upgrades Prometheus-Operator to v0.60.1, Prometheus to v2.39.1 and Thanos to v0.28.1. +This version also upgrades the Helm charts of kube-state-metrics to 4.20.2, prometheus-node-exporter to 4.3.0 and Grafana to 6.40.4. + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +This version splits kubeScheduler recording and altering rules in separate config values. +Instead of `defaultRules.rules.kubeScheduler` the 2 new variables `defaultRules.rules.kubeSchedulerAlerting` and `defaultRules.rules.kubeSchedulerRecording` are used. + +### From 39.x to 40.x + +This version upgrades Prometheus-Operator to v0.59.1, Prometheus to v2.38.0, kube-state-metrics to v2.6.0 and Thanos to v0.28.0. +This version also upgrades the Helm charts of kube-state-metrics to 4.18.0 and prometheus-node-exporter to 4.2.0. + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.59.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +Starting from prometheus-node-exporter version 4.0.0, the `node exporter` chart is using the [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/). Therefore you have to delete the daemonset before you upgrade. + +```console +kubectl delete daemonset -l app=prometheus-node-exporter +helm upgrade -i kube-prometheus-stack prometheus-community/kube-prometheus-stack +``` + +If you use your own custom [ServiceMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor) or [PodMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#podmonitor), please ensure to upgrade their `selector` fields accordingly to the new labels. + +### From 38.x to 39.x + +This upgraded prometheus-operator to v0.58.0 and prometheus to v2.37.0 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 37.x to 38.x + +Reverted one of the default metrics relabelings for cAdvisor added in 36.x, due to it breaking container_network_* and various other statistics. If you do not want this change, you will need to override the `kubelet.cAdvisorMetricRelabelings`. + +### From 36.x to 37.x + +This includes some default metric relabelings for cAdvisor and apiserver metrics to reduce cardinality. If you do not want these defaults, you will need to override the `kubeApiServer.metricRelabelings` and or `kubelet.cAdvisorMetricRelabelings`. + +### From 35.x to 36.x + +This upgraded prometheus-operator to v0.57.0 and prometheus to v2.36.1 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.57.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 34.x to 35.x + +This upgraded prometheus-operator to v0.56.0 and prometheus to v2.35.0 + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.56.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 33.x to 34.x + +This upgrades to prometheus-operator to v0.55.0 and prometheus to v2.33.5. + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.55.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 32.x to 33.x + +This upgrades the prometheus-node-exporter Chart to v3.0.0. Please review the changes to this subchart if you make customizations to hostMountPropagation. + +### From 31.x to 32.x + +This upgrades to prometheus-operator to v0.54.0 and prometheus to v2.33.1. It also changes the default for `grafana.serviceMonitor.enabled` to `true. + +Run these commands to update the CRDs before applying the upgrade. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.54.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 30.x to 31.x + +This version removes the built-in grafana ServiceMonitor and instead relies on the ServiceMonitor of the sub-chart. +`grafana.serviceMonitor.enabled` must be set instead of `grafana.serviceMonitor.selfMonitor` and the old ServiceMonitor may +need to be manually cleaned up after deploying the new release. + +### From 29.x to 30.x + +This version updates kube-state-metrics to 4.3.0 and uses the new option `kube-state-metrics.releaseLabel=true` which adds the "release" label to kube-state-metrics labels, making scraping of the metrics by kube-prometheus-stack work out of the box again, independent of the used kube-prometheus-stack release name. If you already set the "release" label via `kube-state-metrics.customLabels` you might have to remove that and use it via the new option. + +### From 28.x to 29.x + +This version makes scraping port for kube-controller-manager and kube-scheduler dynamic to reflect changes to default serving ports +for those components in Kubernetes versions v1.22 and v1.23 respectively. + +If you deploy on clusters using version v1.22+, kube-controller-manager will be scraped over HTTPS on port 10257. + +If you deploy on clusters running version v1.23+, kube-scheduler will be scraped over HTTPS on port 10259. + +### From 27.x to 28.x + +This version disables PodSecurityPolicies by default because they are deprecated in Kubernetes 1.21 and will be removed in Kubernetes 1.25. + +If you are using PodSecurityPolicies you can enable the previous behaviour by setting `kube-state-metrics.podSecurityPolicy.enabled`, `prometheus-node-exporter.rbac.pspEnabled`, `grafana.rbac.pspEnabled` and `global.rbac.pspEnabled` to `true`. + +### From 26.x to 27.x + +This version splits prometheus-node-exporter chart recording and altering rules in separate config values. +Instead of `defaultRules.rules.node` the 2 new variables `defaultRules.rules.nodeExporterAlerting` and `defaultRules.rules.nodeExporterRecording` are used. + +Also the following defaultRules.rules has been removed as they had no effect: `kubeApiserverError`, `kubePrometheusNodeAlerting`, `kubernetesAbsent`, `time`. + +The ability to set a rubookUrl via `defaultRules.rules.rubookUrl` was reintroduced. + +### From 25.x to 26.x + +This version enables the prometheus-node-exporter subchart servicemonitor by default again, by setting `prometheus-node-exporter.prometheus.monitor.enabled` to `true`. + +### From 24.x to 25.x + +This version upgrade to prometheus-operator v0.53.1. It removes support for setting a runbookUrl, since the upstream format for runbooks changed. + +```console +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 23.x to 24.x + +The custom `ServiceMonitor` for the _kube-state-metrics_ & _prometheus-node-exporter_ charts have been removed in favour of the built-in sub-chart `ServiceMonitor`; for both sub-charts this means that `ServiceMonitor` customisations happen via the values passed to the chart. If you haven't directly customised this behaviour then there are no changes required to upgrade, but if you have please read the following. + +For _kube-state-metrics_ the `ServiceMonitor` customisation is now set via `kube-state-metrics.prometheus.monitor` and the `kubeStateMetrics.serviceMonitor.selfMonitor.enabled` value has moved to `kube-state-metrics.selfMonitor.enabled`. + +For _prometheus-node-exporter_ the `ServiceMonitor` customisation is now set via `prometheus-node-exporter.prometheus.monitor` and the `nodeExporter.jobLabel` values has moved to `prometheus-node-exporter.prometheus.monitor.jobLabel`. + +### From 22.x to 23.x + +Port names have been renamed for Istio's +[explicit protocol selection](https://istio.io/latest/docs/ops/configuration/traffic-management/protocol-selection/#explicit-protocol-selection). + +| | old value | new value | +|-|-----------|-----------| +| `alertmanager.alertmanagerSpec.portName` | `web` | `http-web` | +| `grafana.service.portName` | `service` | `http-web` | +| `prometheus-node-exporter.service.portName` | `metrics` (hardcoded) | `http-metrics` | +| `prometheus.prometheusSpec.portName` | `web` | `http-web` | + +### From 21.x to 22.x + +Due to the upgrade of the `kube-state-metrics` chart, removal of its deployment/stateful needs to done manually prior to upgrading: + +```console +kubectl delete deployments.apps -l app.kubernetes.io/instance=prometheus-operator,app.kubernetes.io/name=kube-state-metrics --cascade=orphan +``` + +or if you use autosharding: + +```console +kubectl delete statefulsets.apps -l app.kubernetes.io/instance=prometheus-operator,app.kubernetes.io/name=kube-state-metrics --cascade=orphan +``` + +### From 20.x to 21.x + +The config reloader values have been refactored. All the values have been moved to the key `prometheusConfigReloader` and the limits and requests can now be set separately. + +### From 19.x to 20.x + +Version 20 upgrades prometheus-operator from 0.50.x to 0.52.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 18.x to 19.x + +`kubeStateMetrics.serviceMonitor.namespaceOverride` was removed. +Please use `kube-state-metrics.namespaceOverride` instead. + +### From 17.x to 18.x + +Version 18 upgrades prometheus-operator from 0.49.x to 0.50.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.50.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 16.x to 17.x + +Version 17 upgrades prometheus-operator from 0.48.x to 0.49.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.49.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 15.x to 16.x + +Version 16 upgrades kube-state-metrics to v2.0.0. This includes changed command-line arguments and removed metrics, see this [blog post](https://kubernetes.io/blog/2021/04/13/kube-state-metrics-v-2-0/). This version also removes Grafana dashboards that supported Kubernetes 1.14 or earlier. + +### From 14.x to 15.x + +Version 15 upgrades prometheus-operator from 0.46.x to 0.47.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.47.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 13.x to 14.x + +Version 14 upgrades prometheus-operator from 0.45.x to 0.46.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRDs manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.46.0/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml +``` + +### From 12.x to 13.x + +Version 13 upgrades prometheus-operator from 0.44.x to 0.45.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRD manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.45.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.45.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.45.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml +``` + +### From 11.x to 12.x + +Version 12 upgrades prometheus-operator from 0.43.x to 0.44.x. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRD manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/release-0.44/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml +``` + +The chart was migrated to support only helm v3 and later. + +### From 10.x to 11.x + +Version 11 upgrades prometheus-operator from 0.42.x to 0.43.x. Starting with 0.43.x an additional `AlertmanagerConfigs` CRD is introduced. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRD manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/release-0.43/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml +``` + +Version 11 removes the deprecated tlsProxy via ghostunnel in favor of native TLS support the prometheus-operator gained with v0.39.0. + +### From 9.x to 10.x + +Version 10 upgrades prometheus-operator from 0.38.x to 0.42.x. Starting with 0.40.x an additional `Probes` CRD is introduced. Helm does not automatically upgrade or install new CRDs on a chart upgrade, so you have to install the CRD manually before updating: + +```console +kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/release-0.42/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +``` + +### From 8.x to 9.x + +Version 9 of the helm chart removes the existing `additionalScrapeConfigsExternal` in favour of `additionalScrapeConfigsSecret`. This change lets users specify the secret name and secret key to use for the additional scrape configuration of prometheus. This is useful for users that have prometheus-operator as a subchart and also have a template that creates the additional scrape configuration. + +### From 7.x to 8.x + +Due to new template functions being used in the rules in version 8.x.x of the chart, an upgrade to Prometheus Operator and Prometheus is necessary in order to support them. First, upgrade to the latest version of 7.x.x + +```console +helm upgrade [RELEASE_NAME] prometheus-community/kube-prometheus-stack --version 7.5.0 +``` + +Then upgrade to 8.x.x + +```console +helm upgrade [RELEASE_NAME] prometheus-community/kube-prometheus-stack --version [8.x.x] +``` + +Minimal recommended Prometheus version for this chart release is `2.12.x` + +### From 6.x to 7.x + +Due to a change in grafana subchart, version 7.x.x now requires Helm >= 2.12.0. + +### From 5.x to 6.x + +Due to a change in deployment labels of kube-state-metrics, the upgrade requires `helm upgrade --force` in order to re-create the deployment. If this is not done an error will occur indicating that the deployment cannot be modified: + +```console +invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/name":"kube-state-metrics"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable +``` + +If this error has already been encountered, a `helm history` command can be used to determine which release has worked, then `helm rollback` to the release, then `helm upgrade --force` to this new one + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: + +```console +helm show values prometheus-community/kube-prometheus-stack +``` + +You may also run `helm show values` on this chart's [dependencies](#dependencies) for additional options. + +### Rancher Monitoring Configuration + +The following table shows values exposed by Rancher Monitoring's additions to the chart: + +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `nameOverride` | Provide a name that should be used instead of the chart name when naming all resources deployed by this chart |`"rancher-monitoring"`| +| `namespaceOverride` | Override the deployment namespace | `"cattle-monitoring-system"` | +| `global.rbac.userRoles.create` | Create default user ClusterRoles to allow users to interact with Prometheus CRs, ConfigMaps, and Secrets | `true` | +| `global.rbac.userRoles.aggregateToDefaultRoles` | Aggregate default user ClusterRoles into default k8s ClusterRoles | `true` | +| `prometheus-adapter.enabled` | Whether to install [prometheus-adapter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-adapter) within the cluster | `true` | +| `prometheus-adapter.prometheus.url` | A URL pointing to the Prometheus deployment within your cluster. The default value is set based on the assumption that you plan to deploy the default Prometheus instance from this chart where `.Values.namespaceOverride=cattle-monitoring-system` and `.Values.nameOverride=rancher-monitoring` | `http://rancher-monitoring-prometheus.cattle-monitoring-system.svc` | +| `prometheus-adapter.prometheus.port` | The port on the Prometheus deployment that Prometheus Adapter can make requests to | `9090` | +| `prometheus.prometheusSpec.ignoreNamespaceSelectors` | Ignore NamespaceSelector settings from the PodMonitor and ServiceMonitor configs. If true, PodMonitors and ServiceMonitors can only discover Pods and Services within the namespace they are deployed into | `false` | + +The following values are enabled for different distributions via [rancher-pushprox](https://github.com/rancher/dev-charts/tree/master/packages/rancher-pushprox). See the rancher-pushprox `README.md` for more information on what all values can be configured for the PushProxy chart. + +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `rkeControllerManager.enabled` | Create a PushProx installation for monitoring kube-controller-manager metrics in RKE clusters | `false` | +| `rkeScheduler.enabled` | Create a PushProx installation for monitoring kube-scheduler metrics in RKE clusters | `false` | +| `rkeProxy.enabled` | Create a PushProx installation for monitoring kube-proxy metrics in RKE clusters | `false` | +| `rkeIngressNginx.enabled` | Create a PushProx installation for monitoring ingress-nginx metrics in RKE clusters | `false` | +| `rkeEtcd.enabled` | Create a PushProx installation for monitoring etcd metrics in RKE clusters | `false` | +| `rke2IngressNginx.enabled` | Create a PushProx installation for monitoring ingress-nginx metrics in RKE2 clusters | `false` | +| `k3sServer.enabled` | Create a PushProx installation for monitoring k3s-server metrics (accounts for kube-controller-manager, kube-scheduler, and kube-proxy metrics) in k3s clusters | `false` | +| `kubeAdmControllerManager.enabled` | Create a PushProx installation for monitoring kube-controller-manager metrics in kubeAdm clusters | `false` | +| `kubeAdmScheduler.enabled` | Create a PushProx installation for monitoring kube-scheduler metrics in kubeAdm clusters | `false` | +| `kubeAdmProxy.enabled` | Create a PushProx installation for monitoring kube-proxy metrics in kubeAdm clusters | `false` | +| `kubeAdmEtcd.enabled` | Create a PushProx installation for monitoring etcd metrics in kubeAdm clusters | `false` | + +### Multiple releases + +The same chart can be used to run multiple Prometheus instances in the same cluster if required. To achieve this, it is necessary to run only one instance of prometheus-operator and a pair of alertmanager pods for an HA configuration, while all other components need to be disabled. To disable a dependency during installation, set `kubeStateMetrics.enabled`, `nodeExporter.enabled` and `grafana.enabled` to `false`. + +## Work-Arounds for Known Issues + +### Running on private GKE clusters + +When Google configure the control plane for private clusters, they automatically configure VPC peering between your Kubernetes cluster’s network and a separate Google managed project. In order to restrict what Google are able to access within your cluster, the firewall rules configured restrict access to your Kubernetes pods. This means that in order to use the webhook component with a GKE private cluster, you must configure an additional firewall rule to allow the GKE control plane access to your webhook pod. + +You can read more information on how to add firewall rules for the GKE control plane nodes in the [GKE docs](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#add_firewall_rules) + +Alternatively, you can disable the hooks by setting `prometheusOperator.admissionWebhooks.enabled=false`. + +## PrometheusRules Admission Webhooks + +With Prometheus Operator version 0.30+, the core Prometheus Operator pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent malformed rules from being added to the cluster. + +### How the Chart Configures the Hooks + +A validating and mutating webhook configuration requires the endpoint to which the request is sent to use TLS. It is possible to set up custom certificates to do this, but in most cases, a self-signed certificate is enough. The setup of this component requires some more complex orchestration when using helm. The steps are created to be idempotent and to allow turning the feature on and off without running into helm quirks. + +1. A pre-install hook provisions a certificate into the same namespace using a format compatible with provisioning using end user certificates. If the certificate already exists, the hook exits. +2. The prometheus operator pod is configured to use a TLS proxy container, which will load that certificate. +3. Validating and Mutating webhook configurations are created in the cluster, with their failure mode set to Ignore. This allows rules to be created by the same chart at the same time, even though the webhook has not yet been fully set up - it does not have the correct CA field set. +4. A post-install hook reads the CA from the secret created by step 1 and patches the Validating and Mutating webhook configurations. This process will allow a custom CA provisioned by some other process to also be patched into the webhook configurations. The chosen failure policy is also patched into the webhook configurations + +### Alternatives + +It should be possible to use [jetstack/cert-manager](https://github.com/jetstack/cert-manager) if a more complete solution is required, but it has not been tested. + +You can enable automatic self-signed TLS certificate provisioning via cert-manager by setting the `prometheusOperator.admissionWebhooks.certManager.enabled` value to true. + +### Limitations + +Because the operator can only run as a single pod, there is potential for this component failure to cause rule deployment failure. Because this risk is outweighed by the benefit of having validation, the feature is enabled by default. + +## Developing Prometheus Rules and Grafana Dashboards + +This chart Grafana Dashboards and Prometheus Rules are just a copy from [prometheus-operator/prometheus-operator](https://github.com/prometheus-operator/prometheus-operator) and other sources, synced (with alterations) by scripts in [hack](hack) folder. In order to introduce any changes you need to first [add them to the original repository](https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/customizations/developing-prometheus-rules-and-grafana-dashboards.md) and then sync there by scripts. + +## Further Information + +For more in-depth documentation of configuration options meanings, please see + +- [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator) +- [Prometheus](https://prometheus.io/docs/introduction/overview/) +- [Grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana#grafana-helm-chart) + +## prometheus.io/scrape + +The prometheus operator does not support annotation-based discovery of services, using the `PodMonitor` or `ServiceMonitor` CRD in its place as they provide far more configuration options. +For information on how to use PodMonitors/ServiceMonitors, please see the documentation on the `prometheus-operator/prometheus-operator` documentation here: + +- [ServiceMonitors](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md#include-servicemonitors) +- [PodMonitors](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md#include-podmonitors) +- [Running Exporters](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/running-exporters.md) + +By default, Prometheus discovers PodMonitors and ServiceMonitors within its namespace, that are labeled with the same release tag as the prometheus-operator release. +Sometimes, you may need to discover custom PodMonitors/ServiceMonitors, for example used to scrape data from third-party applications. +An easy way of doing this, without compromising the default PodMonitors/ServiceMonitors discovery, is allowing Prometheus to discover all PodMonitors/ServiceMonitors within its namespace, without applying label filtering. +To do so, you can set `prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues` and `prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues` to `false`. + +## Migrating from stable/prometheus-operator chart + +## Zero downtime + +Since `kube-prometheus-stack` is fully compatible with the `stable/prometheus-operator` chart, a migration without downtime can be achieved. +However, the old name prefix needs to be kept. If you want the new name please follow the step by step guide below (with downtime). + +You can override the name to achieve this: + +```console +helm upgrade prometheus-operator prometheus-community/kube-prometheus-stack -n monitoring --reuse-values --set nameOverride=prometheus-operator +``` + +**Note**: It is recommended to run this first with `--dry-run --debug`. + +## Redeploy with new name (downtime) + +If the **prometheus-operator** values are compatible with the new **kube-prometheus-stack** chart, please follow the below steps for migration: + +> The guide presumes that chart is deployed in `monitoring` namespace and the deployments are running there. If in other namespace, please replace the `monitoring` to the deployed namespace. + +1. Patch the PersistenceVolume created/used by the prometheus-operator chart to `Retain` claim policy: + + ```console + kubectl patch pv/ -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' + ``` + + **Note:** To execute the above command, the user must have a cluster wide permission. Please refer [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) + +2. Uninstall the **prometheus-operator** release and delete the existing PersistentVolumeClaim, and verify PV become Released. + + ```console + helm uninstall prometheus-operator -n monitoring + kubectl delete pvc/ -n monitoring + ``` + + Additionally, you have to manually remove the remaining `prometheus-operator-kubelet` service. + + ```console + kubectl delete service/prometheus-operator-kubelet -n kube-system + ``` + + You can choose to remove all your existing CRDs (ServiceMonitors, Podmonitors, etc.) if you want to. + +3. Remove current `spec.claimRef` values to change the PV's status from Released to Available. + + ```console + kubectl patch pv/ --type json -p='[{"op": "remove", "path": "/spec/claimRef"}]' -n monitoring + ``` + +**Note:** To execute the above command, the user must have a cluster wide permission. Please refer to [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) + +After these steps, proceed to a fresh **kube-prometheus-stack** installation and make sure the current release of **kube-prometheus-stack** matching the `volumeClaimTemplate` values in the `values.yaml`. + +The binding is done via matching a specific amount of storage requested and with certain access modes. + +For example, if you had storage specified as this with **prometheus-operator**: + +```yaml +volumeClaimTemplate: + spec: + storageClassName: gp2 + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 50Gi +``` + +You have to specify matching `volumeClaimTemplate` with 50Gi storage and `ReadWriteOnce` access mode. + +Additionally, you should check the current AZ of your legacy installation's PV, and configure the fresh release to use the same AZ as the old one. If the pods are in a different AZ than the PV, the release will fail to bind the existing one, hence creating a new PV. + +This can be achieved either by specifying the labels through `values.yaml`, e.g. setting `prometheus.prometheusSpec.nodeSelector` to: + +```yaml +nodeSelector: + failure-domain.beta.kubernetes.io/zone: east-west-1a +``` + +or passing these values as `--set` overrides during installation. + +The new release should now re-attach your previously released PV with its content. + +## Migrating from coreos/prometheus-operator chart + +The multiple charts have been combined into a single chart that installs prometheus operator, prometheus, alertmanager, grafana as well as the multitude of exporters necessary to monitor a cluster. + +There is no simple and direct migration path between the charts as the changes are extensive and intended to make the chart easier to support. + +The capabilities of the old chart are all available in the new chart, including the ability to run multiple prometheus instances on a single cluster - you will need to disable the parts of the chart you do not wish to deploy. + +You can check out the tickets for this change [here](https://github.com/prometheus-operator/prometheus-operator/issues/592) and [here](https://github.com/helm/charts/pull/6765). + +### High-level overview of Changes + +#### Added dependencies + +The chart has added 3 [dependencies](#dependencies). + +- Node-Exporter, Kube-State-Metrics: These components are loaded as dependencies into the chart, and are relatively simple components +- Grafana: The Grafana chart is more feature-rich than this chart - it contains a sidecar that is able to load data sources and dashboards from configmaps deployed into the same cluster. For more information check out the [documentation for the chart](https://github.com/grafana/helm-charts/blob/main/charts/grafana/README.md) + +#### Kubelet Service + +Because the kubelet service has a new name in the chart, make sure to clean up the old kubelet service in the `kube-system` namespace to prevent counting container metrics twice. + +#### Persistent Volumes + +If you would like to keep the data of the current persistent volumes, it should be possible to attach existing volumes to new PVCs and PVs that are created using the conventions in the new chart. For example, in order to use an existing Azure disk for a helm release called `prometheus-migration` the following resources can be created: + +```yaml +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pvc-prometheus-migration-prometheus-0 +spec: + accessModes: + - ReadWriteOnce + azureDisk: + cachingMode: None + diskName: pvc-prometheus-migration-prometheus-0 + diskURI: /subscriptions/f5125d82-2622-4c50-8d25-3f7ba3e9ac4b/resourceGroups/sample-migration-resource-group/providers/Microsoft.Compute/disks/pvc-prometheus-migration-prometheus-0 + fsType: "" + kind: Managed + readOnly: false + capacity: + storage: 1Gi + persistentVolumeReclaimPolicy: Delete + storageClassName: prometheus + volumeMode: Filesystem +``` + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + app.kubernetes.io/name: prometheus + prometheus: prometheus-migration-prometheus + name: prometheus-prometheus-migration-prometheus-db-prometheus-prometheus-migration-prometheus-0 + namespace: monitoring +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: prometheus + volumeMode: Filesystem + volumeName: pvc-prometheus-migration-prometheus-0 +``` + +The PVC will take ownership of the PV and when you create a release using a persistent volume claim template it will use the existing PVCs as they match the naming convention used by the chart. For other cloud providers similar approaches can be used. + +#### KubeProxy + +The metrics bind address of kube-proxy is default to `127.0.0.1:10249` that prometheus instances **cannot** access to. You should expose metrics by changing `metricsBindAddress` field value to `0.0.0.0:10249` if you want to collect them. + +Depending on the cluster, the relevant part `config.conf` will be in ConfigMap `kube-system/kube-proxy` or `kube-system/kube-proxy-config`. For example: + +```console +kubectl -n kube-system edit cm kube-proxy +``` + +```yaml +apiVersion: v1 +data: + config.conf: |- + apiVersion: kubeproxy.config.k8s.io/v1alpha1 + kind: KubeProxyConfiguration + # ... + # metricsBindAddress: 127.0.0.1:10249 + metricsBindAddress: 0.0.0.0:10249 + # ... + kubeconfig.conf: |- + # ... +kind: ConfigMap +metadata: + labels: + app: kube-proxy + name: kube-proxy + namespace: kube-system +``` diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/app-README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/app-README.md new file mode 100644 index 0000000000..3920854384 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/app-README.md @@ -0,0 +1,46 @@ +# Rancher Monitoring and Alerting + + This chart is based on the upstream [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) chart. The chart deploys [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator) and its CRDs along with [Grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana), [Prometheus Adapter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-adapter) and additional charts / Kubernetes manifests to gather metrics. It allows users to monitor their Kubernetes clusters, view metrics in Grafana dashboards, and set up alerts and notifications. + +For more information on how to use the feature, refer to our [docs](https://rancher.com/docs/rancher/v2.x/en/monitoring-alerting/v2.5/). + +The chart installs the following components: + +- [Prometheus Operator](https://github.com/coreos/prometheus-operator) - The operator provides easy monitoring definitions for Kubernetes services, manages [Prometheus](https://prometheus.io/) and [AlertManager](https://prometheus.io/docs/alerting/latest/alertmanager/) instances, and adds default scrape targets for some Kubernetes components. +- [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus/) - A collection of community-curated Kubernetes manifests, Grafana Dashboards, and PrometheusRules that deploy a default end-to-end cluster monitoring configuration. +- [Grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana) - Grafana allows a user to create / view dashboards based on the cluster metrics collected by Prometheus. +- [node-exporter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-node-exporter) / [kube-state-metrics](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics) / [rancher-pushprox](https://github.com/rancher/charts/tree/dev-v2.7/packages/rancher-monitoring/rancher-pushprox/charts) - These charts monitor various Kubernetes components across different Kubernetes cluster types. +- [Prometheus Adapter](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-adapter) - The adapter allows a user to expose custom metrics, resource metrics, and external metrics on the default [Prometheus](https://prometheus.io/) instance to the Kubernetes API Server. + +For more information, review the Helm README of this chart. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. +​ +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Upgrading from 100.0.0+up16.6.0 to 100.1.0+up19.0.3 + +### Noticeable changes: +Grafana: +- `sidecar.dashboards.searchNamespace`, `sidecar.datasources.searchNamespace` and `sidecar.notifiers.searchNamespace` support a list of namespaces now. + +Kube-state-metrics +- the type of `collectors` is changed from Dictionary to List. +- `kubeStateMetrics.serviceMonitor.namespaceOverride` was replaced by `kube-state-metrics.namespaceOverride`. + +### Known issues: +- Occasionally, the upgrade fails with errors related to the webhook `prometheusrulemutate.monitoring.coreos.com`. This is a known issue in the upstream, and the workaround is to trigger the upgrade one more time. [32416](https://github.com/rancher/rancher/issues/32416#issuecomment-828881726) diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/.helmignore new file mode 100644 index 0000000000..8cade1318f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/.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 +.vscode +.project +.idea/ +*.tmproj +OWNERS diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/Chart.yaml new file mode 100644 index 0000000000..7770ebbe5a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/Chart.yaml @@ -0,0 +1,41 @@ +annotations: + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/grafana/helm-charts + - name: Upstream Project + url: https://github.com/grafana/grafana + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-grafana +apiVersion: v2 +appVersion: 11.1.0 +description: The leading tool for querying and visualizing time series and metrics. +home: https://grafana.com +icon: https://artifacthub.io/image/b4fed1a7-6c8f-4945-b99d-096efa3e4116 +keywords: +- monitoring +- metric +kubeVersion: '>=1.28.0-0' +maintainers: +- email: zanhsieh@gmail.com + name: zanhsieh +- email: rluckie@cisco.com + name: rtluckie +- email: maor.friedman@redhat.com + name: maorfr +- email: miroslav.hadzhiev@gmail.com + name: Xtigyro +- email: mail@torstenwalter.de + name: torstenwalter +- email: github@jkroepke.de + name: jkroepke +name: grafana +sources: +- https://github.com/grafana/grafana +- https://github.com/grafana/helm-charts +type: application +version: 8.3.6 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/README.md new file mode 100644 index 0000000000..f758963a4b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/README.md @@ -0,0 +1,778 @@ +# Grafana Helm Chart + +* Installs the web dashboarding system [Grafana](http://grafana.org/) + +## 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 +``` + +## 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. + +### To 4.0.0 (And 3.12.1) + +This version requires Helm >= 2.12.0. + +### To 5.0.0 + +You have to add --force to your helm upgrade command as the labels of the chart have changed. + +### To 6.0.0 + +This version requires Helm >= 3.1.0. + +### To 7.0.0 + +For consistency with other Helm charts, the `global.image.registry` parameter was renamed +to `global.imageRegistry`. If you were not previously setting `global.image.registry`, no action +is required on upgrade. If you were previously setting `global.image.registry`, you will +need to instead set `global.imageRegistry`. + +## Configuration + +| Parameter | Description | Default | +|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| +| `replicas` | Number of nodes | `1` | +| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | +| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `nil` | +| `podDisruptionBudget.apiVersion` | Pod disruption apiVersion | `nil` | +| `deploymentStrategy` | Deployment strategy | `{ "type": "RollingUpdate" }` | +| `livenessProbe` | Liveness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10 }` | +| `readinessProbe` | Readiness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } }`| +| `securityContext` | Deployment securityContext | `{"runAsUser": 472, "runAsGroup": 472, "fsGroup": 472}` | +| `priorityClassName` | Name of Priority Class to assign pods | `nil` | +| `image.registry` | Image registry | `docker.io` | +| `image.repository` | Image repository | `grafana/grafana` | +| `image.tag` | Overrides the Grafana image tag whose default is the chart appVersion (`Must be >= 5.0.0`) | `` | +| `image.sha` | Image sha (optional) | `` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Image pull secrets (can be templated) | `[]` | +| `service.enabled` | Enable grafana service | `true` | +| `service.ipFamilies` | Kubernetes service IP families | `[]` | +| `service.ipFamilyPolicy` | Kubernetes service IP family policy | `""` | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.port` | Kubernetes port where service is exposed | `80` | +| `service.portName` | Name of the port on the service | `service` | +| `service.appProtocol` | Adds the appProtocol field to the service | `` | +| `service.targetPort` | Internal service is port | `3000` | +| `service.nodePort` | Kubernetes service nodePort | `nil` | +| `service.annotations` | Service annotations (can be templated) | `{}` | +| `service.labels` | Custom labels | `{}` | +| `service.clusterIP` | internal cluster service IP | `nil` | +| `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `nil` | +| `service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to lb (if supported) | `[]` | +| `service.externalIPs` | service external IP addresses | `[]` | +| `service.externalTrafficPolicy` | change the default externalTrafficPolicy | `nil` | +| `headlessService` | Create a headless service | `false` | +| `extraExposePorts` | Additional service ports for sidecar containers| `[]` | +| `hostAliases` | adds rules to the pod's /etc/hosts | `[]` | +| `ingress.enabled` | Enables Ingress | `false` | +| `ingress.annotations` | Ingress annotations (values are templated) | `{}` | +| `ingress.labels` | Custom labels | `{}` | +| `ingress.path` | Ingress accepted path | `/` | +| `ingress.pathType` | Ingress type of path | `Prefix` | +| `ingress.hosts` | Ingress accepted hostnames | `["chart-example.local"]` | +| `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/guide/ingress/annotations/#actions). Requires `ingress.hosts` to have one or more host entries. | `[]` | +| `ingress.tls` | Ingress TLS configuration | `[]` | +| `ingress.ingressClassName` | Ingress Class Name. MAY be required for Kubernetes versions >= 1.18 | `""` | +| `resources` | CPU/Memory resource requests/limits | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Toleration labels for pod assignment | `[]` | +| `affinity` | Affinity settings for pod assignment | `{}` | +| `extraInitContainers` | Init containers to add to the grafana pod | `{}` | +| `extraContainers` | Sidecar containers to add to the grafana pod | `""` | +| `extraContainerVolumes` | Volumes that can be mounted in sidecar containers | `[]` | +| `extraLabels` | Custom labels for all manifests | `{}` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | +| `persistence.enabled` | Use persistent volume to store data | `false` | +| `persistence.type` | Type of persistence (`pvc` or `statefulset`) | `pvc` | +| `persistence.size` | Size of persistent volume claim | `10Gi` | +| `persistence.existingClaim` | Use an existing PVC to persist data (can be templated) | `nil` | +| `persistence.storageClassName` | Type of persistent volume claim | `nil` | +| `persistence.accessModes` | Persistence access modes | `[ReadWriteOnce]` | +| `persistence.annotations` | PersistentVolumeClaim annotations | `{}` | +| `persistence.finalizers` | PersistentVolumeClaim finalizers | `[ "kubernetes.io/pvc-protection" ]` | +| `persistence.extraPvcLabels` | Extra labels to apply to a PVC. | `{}` | +| `persistence.subPath` | Mount a sub dir of the persistent volume (can be templated) | `nil` | +| `persistence.inMemory.enabled` | If persistence is not enabled, whether to mount the local storage in-memory to improve performance | `false` | +| `persistence.inMemory.sizeLimit` | SizeLimit for the in-memory local storage | `nil` | +| `persistence.disableWarning` | Hide NOTES warning, useful when persiting to a database | `false` | +| `initChownData.enabled` | If false, don't reset data ownership at startup | true | +| `initChownData.image.registry` | init-chown-data container image registry | `docker.io` | +| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | +| `initChownData.image.tag` | init-chown-data container image tag | `1.31.1` | +| `initChownData.image.sha` | init-chown-data container image sha (optional)| `""` | +| `initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` | +| `initChownData.resources` | init-chown-data pod resource requests & limits | `{}` | +| `schedulerName` | Alternate scheduler name | `nil` | +| `env` | Extra environment variables passed to pods | `{}` | +| `envValueFrom` | Environment variables from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | +| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `envFromSecrets` | List of Kubernetes secrets (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | +| `envFromConfigMaps` | List of Kubernetes ConfigMaps (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | +| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret. (passed through [tpl](https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function)) | `{}` | +| `enableServiceLinks` | Inject Kubernetes services as environment variables. | `true` | +| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | +| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | +| `extraVolumes` | Additional Grafana server volumes | `[]` | +| `automountServiceAccountToken` | Mounted the service account token on the grafana pod. Mandatory, if sidecars are enabled | `true` | +| `createConfigmap` | Enable creating the grafana configmap | `true` | +| `extraConfigmapMounts` | Additional grafana server configMap volume mounts (values are templated) | `[]` | +| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | +| `plugins` | Plugins to be loaded along with Grafana | `[]` | +| `datasources` | Configure grafana datasources (passed through tpl) | `{}` | +| `alerting` | Configure grafana alerting (passed through tpl) | `{}` | +| `notifiers` | Configure grafana notifiers | `{}` | +| `dashboardProviders` | Configure grafana dashboard providers | `{}` | +| `dashboards` | Dashboards to import | `{}` | +| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` | +| `grafana.ini` | Grafana's primary configuration | `{}` | +| `global.imageRegistry` | Global image pull registry for all images. | `null` | +| `global.imagePullSecrets` | Global image pull secrets (can be templated). Allows either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). | `[]` | +| `ldap.enabled` | Enable LDAP authentication | `false` | +| `ldap.existingSecret` | The name of an existing secret containing the `ldap.toml` file, this must have the key `ldap-toml`. | `""` | +| `ldap.config` | Grafana's LDAP configuration | `""` | +| `annotations` | Deployment annotations | `{}` | +| `labels` | Deployment labels | `{}` | +| `podAnnotations` | Pod annotations | `{}` | +| `podLabels` | Pod labels | `{}` | +| `podPortName` | Name of the grafana port on the pod | `grafana` | +| `lifecycleHooks` | Lifecycle hooks for podStart and preStop [Example](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/#define-poststart-and-prestop-handlers) | `{}` | +| `sidecar.image.registry` | Sidecar image registry | `quay.io` | +| `sidecar.image.repository` | Sidecar image repository | `kiwigrid/k8s-sidecar` | +| `sidecar.image.tag` | Sidecar image tag | `1.26.0` | +| `sidecar.image.sha` | Sidecar image sha (optional) | `""` | +| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | +| `sidecar.resources` | Sidecar resources | `{}` | +| `sidecar.securityContext` | Sidecar securityContext | `{}` | +| `sidecar.enableUniqueFilenames` | Sets the kiwigrid/k8s-sidecar UNIQUE_FILENAMES environment variable. If set to `true` the sidecar will create unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | `false` | +| `sidecar.alerts.enabled` | Enables the cluster wide search for alerts and adds/updates/deletes them in grafana |`false` | +| `sidecar.alerts.label` | Label that config maps with alerts should have to be added | `grafana_alert` | +| `sidecar.alerts.labelValue` | Label value that config maps with alerts should have to be added | `""` | +| `sidecar.alerts.searchNamespace` | Namespaces list. If specified, the sidecar will search for alerts config-maps 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. | `nil` | +| `sidecar.alerts.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.alerts.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.alerts.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/alerting/reload"` | +| `sidecar.alerts.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.alerts.initAlerts` | Set to true to deploy the alerts sidecar as an initContainer. This is needed if skipReload is true, to load any alerts defined at startup time. | `false` | +| `sidecar.alerts.extraMounts` | Additional alerts sidecar volume mounts. | `[]` | +| `sidecar.dashboards.enabled` | Enables the cluster wide search for dashboards and adds/updates/deletes them in grafana | `false` | +| `sidecar.dashboards.SCProvider` | Enables creation of sidecar provider | `true` | +| `sidecar.dashboards.provider.name` | Unique name of the grafana provider | `sidecarProvider` | +| `sidecar.dashboards.provider.orgid` | Id of the organisation, to which the dashboards should be added | `1` | +| `sidecar.dashboards.provider.folder` | Logical folder in which grafana groups dashboards | `""` | +| `sidecar.dashboards.provider.folderUid` | Allows you to specify the static UID for the logical folder above | `""` | +| `sidecar.dashboards.provider.disableDelete` | Activate to avoid the deletion of imported dashboards | `false` | +| `sidecar.dashboards.provider.allowUiUpdates` | Allow updating provisioned dashboards from the UI | `false` | +| `sidecar.dashboards.provider.type` | Provider type | `file` | +| `sidecar.dashboards.provider.foldersFromFilesStructure` | Allow Grafana to replicate dashboard structure from filesystem. | `false` | +| `sidecar.dashboards.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.skipTlsVerify` | Set to true to skip tls verification for kube api calls | `nil` | +| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | `grafana_dashboard` | +| `sidecar.dashboards.labelValue` | Label value that config maps with dashboards should have to be added | `""` | +| `sidecar.dashboards.folder` | Folder in the pod that should hold the collected dashboards (unless `sidecar.dashboards.defaultFolderName` is set). This path will be mounted. | `/tmp/dashboards` | +| `sidecar.dashboards.folderAnnotation` | The annotation the sidecar will look for in configmaps to override the destination folder for files | `nil` | +| `sidecar.dashboards.defaultFolderName` | The default folder name, it will create a subfolder under the `sidecar.dashboards.folder` and put dashboards in there instead | `nil` | +| `sidecar.dashboards.searchNamespace` | Namespaces list. If specified, the sidecar will search for dashboards config-maps 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. | `nil` | +| `sidecar.dashboards.script` | Absolute path to shell script to execute after a configmap got reloaded. | `nil` | +| `sidecar.dashboards.reloadURL` | Full url of dashboards configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/dashboards/reload"` | +| `sidecar.dashboards.skipReload` | Enabling this omits defining the REQ_USERNAME, REQ_PASSWORD, REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.dashboards.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.dashboards.extraMounts` | Additional dashboard sidecar volume mounts. | `[]` | +| `sidecar.datasources.enabled` | Enables the cluster wide search for datasources and adds/updates/deletes them in grafana |`false` | +| `sidecar.datasources.label` | Label that config maps with datasources should have to be added | `grafana_datasource` | +| `sidecar.datasources.labelValue` | Label value that config maps with datasources should have to be added | `""` | +| `sidecar.datasources.searchNamespace` | Namespaces list. If specified, the sidecar will search for datasources config-maps 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. | `nil` | +| `sidecar.datasources.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.datasources.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.datasources.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | +| `sidecar.datasources.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.datasources.initDatasources` | Set to true to deploy the datasource sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any datasources defined at startup time. | `false` | +| `sidecar.notifiers.enabled` | Enables the cluster wide search for notifiers and adds/updates/deletes them in grafana | `false` | +| `sidecar.notifiers.label` | Label that config maps with notifiers should have to be added | `grafana_notifier` | +| `sidecar.notifiers.labelValue` | Label value that config maps with notifiers should have to be added | `""` | +| `sidecar.notifiers.searchNamespace` | Namespaces list. If specified, the sidecar will search for notifiers config-maps (or 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. | `nil` | +| `sidecar.notifiers.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.notifiers.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.notifiers.reloadURL` | Full url of notifier configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/notifications/reload"` | +| `sidecar.notifiers.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.notifiers.initNotifiers` | Set to true to deploy the notifier sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any notifiers defined at startup time. | `false` | +| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials. | `""` | +| `smtp.userKey` | The key in the existing SMTP secret containing the username. | `"user"` | +| `smtp.passwordKey` | The key in the existing SMTP secret containing the password. | `"password"` | +| `admin.existingSecret` | The name of an existing secret containing the admin credentials (can be templated). | `""` | +| `admin.userKey` | The key in the existing admin secret containing the username. | `"admin-user"` | +| `admin.passwordKey` | The key in the existing admin secret containing the password. | `"admin-password"` | +| `serviceAccount.automountServiceAccountToken` | Automount the service account token on all pods where is service account is used | `false` | +| `serviceAccount.annotations` | ServiceAccount annotations | | +| `serviceAccount.create` | Create service account | `true` | +| `serviceAccount.labels` | ServiceAccount labels | `{}` | +| `serviceAccount.name` | Service account name to use, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `` | +| `serviceAccount.nameTest` | Service account name to use for test, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `nil` | +| `rbac.create` | Create and use RBAC resources | `true` | +| `rbac.namespaced` | Creates Role and Rolebinding instead of the default ClusterRole and ClusteRoleBindings for the grafana instance | `false` | +| `rbac.useExistingRole` | Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. | `nil` | +| `rbac.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `false` | +| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `false` | +| `rbac.extraRoleRules` | Additional rules to add to the Role | [] | +| `rbac.extraClusterRoleRules` | Additional rules to add to the ClusterRole | [] | +| `command` | Define command to be executed by grafana container at startup | `nil` | +| `args` | Define additional args if command is used | `nil` | +| `testFramework.enabled` | Whether to create test-related resources | `true` | +| `testFramework.image.registry` | `test-framework` image registry. | `docker.io` | +| `testFramework.image.repository` | `test-framework` image repository. | `bats/bats` | +| `testFramework.image.tag` | `test-framework` image tag. | `v1.4.1` | +| `testFramework.imagePullPolicy` | `test-framework` image pull policy. | `IfNotPresent` | +| `testFramework.securityContext` | `test-framework` securityContext | `{}` | +| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | +| `downloadDashboards.envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `downloadDashboards.resources` | Resources of `download-dashboards` container | `{}` | +| `downloadDashboardsImage.registry` | Curl docker image registry | `docker.io` | +| `downloadDashboardsImage.repository` | Curl docker image repository | `curlimages/curl` | +| `downloadDashboardsImage.tag` | Curl docker image tag | `7.73.0` | +| `downloadDashboardsImage.sha` | Curl docker image sha (optional) | `""` | +| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | +| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | +| `serviceMonitor.enabled` | Use servicemonitor from prometheus operator | `false` | +| `serviceMonitor.namespace` | Namespace this servicemonitor is installed in | | +| `serviceMonitor.interval` | How frequently Prometheus should scrape | `1m` | +| `serviceMonitor.path` | Path to scrape | `/metrics` | +| `serviceMonitor.scheme` | Scheme to use for metrics scraping | `http` | +| `serviceMonitor.tlsConfig` | TLS configuration block for the endpoint | `{}` | +| `serviceMonitor.labels` | Labels for the servicemonitor passed to Prometheus Operator | `{}` | +| `serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `30s` | +| `serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping. | `[]` | +| `serviceMonitor.metricRelabelings` | MetricRelabelConfigs to apply to samples before ingestion. | `[]` | +| `revisionHistoryLimit` | Number of old ReplicaSets to retain | `10` | +| `imageRenderer.enabled` | Enable the image-renderer deployment & service | `false` | +| `imageRenderer.image.registry` | image-renderer Image registry | `docker.io` | +| `imageRenderer.image.repository` | image-renderer Image repository | `grafana/grafana-image-renderer` | +| `imageRenderer.image.tag` | image-renderer Image tag | `latest` | +| `imageRenderer.image.sha` | image-renderer Image sha (optional) | `""` | +| `imageRenderer.image.pullPolicy` | image-renderer ImagePullPolicy | `Always` | +| `imageRenderer.env` | extra env-vars for image-renderer | `{}` | +| `imageRenderer.envValueFrom` | Environment variables for image-renderer from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | +| `imageRenderer.extraConfigmapMounts` | Additional image-renderer configMap volume mounts (values are templated) | `[]` | +| `imageRenderer.extraSecretMounts` | Additional image-renderer secret volume mounts | `[]` | +| `imageRenderer.extraVolumeMounts` | Additional image-renderer volume mounts | `[]` | +| `imageRenderer.extraVolumes` | Additional image-renderer volumes | `[]` | +| `imageRenderer.serviceAccountName` | image-renderer deployment serviceAccountName | `""` | +| `imageRenderer.securityContext` | image-renderer deployment securityContext | `{}` | +| `imageRenderer.podAnnotations` | image-renderer image-renderer pod annotation | `{}` | +| `imageRenderer.hostAliases` | image-renderer deployment Host Aliases | `[]` | +| `imageRenderer.priorityClassName` | image-renderer deployment priority class | `''` | +| `imageRenderer.service.enabled` | Enable the image-renderer service | `true` | +| `imageRenderer.service.portName` | image-renderer service port name | `http` | +| `imageRenderer.service.port` | image-renderer port used by deployment | `8081` | +| `imageRenderer.service.targetPort` | image-renderer service port used by service | `8081` | +| `imageRenderer.appProtocol` | Adds the appProtocol field to the service | `` | +| `imageRenderer.grafanaSubPath` | Grafana sub path to use for image renderer callback url | `''` | +| `imageRenderer.podPortName` | name of the image-renderer port on the pod | `http` | +| `imageRenderer.revisionHistoryLimit` | number of image-renderer replica sets to keep | `10` | +| `imageRenderer.networkPolicy.limitIngress` | Enable a NetworkPolicy to limit inbound traffic from only the created grafana pods | `true` | +| `imageRenderer.networkPolicy.limitEgress` | Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods | `false` | +| `imageRenderer.resources` | Set resource limits for image-renderer pods | `{}` | +| `imageRenderer.nodeSelector` | Node labels for pod assignment | `{}` | +| `imageRenderer.tolerations` | Toleration labels for pod assignment | `[]` | +| `imageRenderer.affinity` | Affinity settings for pod assignment | `{}` | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed | `{}` | +| `networkPolicy.ingress` | Enable the creation of an ingress network policy | `true` | +| `networkPolicy.egress.enabled` | Enable the creation of an egress network policy | `false` | +| `networkPolicy.egress.ports` | An array of ports to allow for the egress | `[]` | +| `enableKubeBackwardCompatibility` | Enable backward compatibility of kubernetes where pod's defintion version below 1.13 doesn't have the enableServiceLinks option | `false` | + +### Example ingress with path + +With grafana 6.3 and above + +```yaml +grafana.ini: + server: + domain: monitoring.example.com + root_url: "%(protocol)s://%(domain)s/grafana" + serve_from_sub_path: true +ingress: + enabled: true + hosts: + - "monitoring.example.com" + path: "/grafana" +``` + +### Example of extraVolumeMounts and extraVolumes + +Configure additional volumes with `extraVolumes` and volume mounts with `extraVolumeMounts`. + +Example for `extraVolumeMounts` and corresponding `extraVolumes`: + +```yaml +extraVolumeMounts: + - name: plugins + mountPath: /var/lib/grafana/plugins + subPath: configs/grafana/plugins + readOnly: false + - name: dashboards + mountPath: /var/lib/grafana/dashboards + hostPath: /usr/shared/grafana/dashboards + readOnly: false + +extraVolumes: + - name: plugins + existingClaim: existing-grafana-claim + - name: dashboards + hostPath: /usr/shared/grafana/dashboards +``` + +Volumes default to `emptyDir`. Set to `persistentVolumeClaim`, +`hostPath`, `csi`, or `configMap` for other types. For a +`persistentVolumeClaim`, specify an existing claim name with +`existingClaim`. + +## Import dashboards + +There are a few methods to import dashboards to Grafana. Below are some examples and explanations as to how to use each method: + +```yaml +dashboards: + default: + some-dashboard: + json: | + { + "annotations": + + ... + # Complete json file here + ... + + "title": "Some Dashboard", + "uid": "abcd1234", + "version": 1 + } + custom-dashboard: + # This is a path to a file inside the dashboards directory inside the chart directory + file: dashboards/custom-dashboard.json + prometheus-stats: + # Ref: https://grafana.com/dashboards/2 + gnetId: 2 + revision: 2 + datasource: Prometheus + loki-dashboard-quick-search: + gnetId: 12019 + revision: 2 + datasource: + - name: DS_PROMETHEUS + value: Prometheus + - name: DS_LOKI + value: Loki + local-dashboard: + url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json +``` + +## BASE64 dashboards + +Dashboards could be stored on a server that does not return JSON directly and instead of it returns a Base64 encoded file (e.g. Gerrit) +A new parameter has been added to the url use case so if you specify a b64content value equals to true after the url entry a Base64 decoding is applied before save the file to disk. +If this entry is not set or is equals to false not decoding is applied to the file before saving it to disk. + +### Gerrit use case + +Gerrit API for download files has the following schema: where {project-name} and +{file-id} usually has '/' in their values and so they MUST be replaced by %2F so if project-name is user/repo, branch-id is master and file-id is equals to dir1/dir2/dashboard +the url value is + +## Sidecar for dashboards + +If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana +pod. This container watches all configmaps (or secrets) in the cluster and filters out the ones with +a label as defined in `sidecar.dashboards.label`. The files defined in those configmaps are written +to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported +dashboards are deleted/updated. + +A recommendation is to use one configmap per dashboard, as a reduction of multiple dashboards inside +one configmap is currently not properly mirrored in grafana. + +Example dashboard config: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: sample-grafana-dashboard + labels: + grafana_dashboard: "1" +data: + k8s-dashboard.json: |- + [...] +``` + +## Sidecar for datasources + +If the parameter `sidecar.datasources.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the data sources in grafana can be imported. + +Should you aim for reloading datasources in Grafana each time the config is changed, set `sidecar.datasources.skipReload: false` and adjust `sidecar.datasources.reloadURL` to `http://..svc.cluster.local/api/admin/provisioning/datasources/reload`. + +Secrets are recommended over configmaps for this usecase because datasources usually contain private +data like usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example values to add a postgres datasource as a kubernetes secret: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: grafana-datasources + labels: + grafana_datasource: 'true' # default value for: sidecar.datasources.label +stringData: + pg-db.yaml: |- + apiVersion: 1 + datasources: + - name: My pg db datasource + type: postgres + url: my-postgresql-db:5432 + user: db-readonly-user + secureJsonData: + password: 'SUperSEcretPa$$word' + jsonData: + database: my_datase + sslmode: 'disable' # disable/require/verify-ca/verify-full + maxOpenConns: 0 # Grafana v5.4+ + maxIdleConns: 2 # Grafana v5.4+ + connMaxLifetime: 14400 # Grafana v5.4+ + postgresVersion: 1000 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10 + timescaledb: false + # allow users to edit datasources from the UI. + editable: false +``` + +Example values to add a datasource adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): + +```yaml +datasources: + datasources.yaml: + apiVersion: 1 + datasources: + # name of the datasource. Required + - name: Graphite + # datasource type. Required + type: graphite + # access mode. proxy or direct (Server or Browser in the UI). Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://localhost:8080 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: + # basic auth username + basicAuthUser: + # basic auth password + basicAuthPassword: + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: true + tlsAuthWithCACert: true + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: false +``` + +## Sidecar for notifiers + +If the parameter `sidecar.notifiers.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.notifiers.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the notification channels in grafana can be imported. The secrets must be created before +`helm install` so that the notifiers init container can list the secrets. + +Secrets are recommended over configmaps for this usecase because alert notification channels usually contain +private data like SMTP usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example datasource config adapted from [Grafana](https://grafana.com/docs/grafana/latest/administration/provisioning/#alert-notification-channels): + +```yaml +notifiers: + - name: notification-channel-1 + type: slack + uid: notifier1 + # either + org_id: 2 + # or + org_name: Main Org. + is_default: true + send_reminder: true + frequency: 1h + disable_resolve_message: false + # See `Supported Settings` section for settings supporter for each + # alert notification type. + settings: + recipient: 'XXX' + token: 'xoxb' + uploadImage: true + url: https://slack.com + +delete_notifiers: + - name: notification-channel-1 + uid: notifier1 + org_id: 2 + - name: notification-channel-2 + # default org_id: 1 +``` + +## Sidecar for alerting resources + +If the parameter `sidecar.alerts.enabled` is set, a sidecar container is deployed in the grafana +pod. This container watches all configmaps (or secrets) in the cluster (namespace defined by `sidecar.alerts.searchNamespace`) and filters out the ones with +a label as defined in `sidecar.alerts.label` (default is `grafana_alert`). The files defined in those configmaps are written +to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported alerting resources are updated, however, deletions are a little more complicated (see below). + +This sidecar can be used to provision alert rules, contact points, notification policies, notification templates and mute timings as shown in [Grafana Documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/). + +To fetch the alert config which will be provisioned, use the alert provisioning API ([Grafana Documentation](https://grafana.com/docs/grafana/next/developers/http_api/alerting_provisioning/)). +You can use either JSON or YAML format. + +Example config for an alert rule: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: sample-grafana-alert + labels: + grafana_alert: "1" +data: + k8s-alert.yml: |- + apiVersion: 1 + groups: + - orgId: 1 + name: k8s-alert + [...] +``` + +To delete provisioned alert rules is a two step process, you need to delete the configmap which defined the alert rule +and then create a configuration which deletes the alert rule. + +Example deletion configuration: +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: delete-sample-grafana-alert + namespace: monitoring + labels: + grafana_alert: "1" +data: + delete-k8s-alert.yml: |- + apiVersion: 1 + deleteRules: + - orgId: 1 + uid: 16624780-6564-45dc-825c-8bded4ad92d3 +``` + +## Statically provision alerting resources +If you don't need to change alerting resources (alert rules, contact points, notification policies and notification templates) regularly you could use the `alerting` config option instead of the sidecar option above. +This will grab the alerting config and apply it statically at build time for the helm file. + +There are two methods to statically provision alerting configuration in Grafana. Below are some examples and explanations as to how to use each method: + +```yaml +alerting: + team1-alert-rules.yaml: + file: alerting/team1/rules.yaml + team2-alert-rules.yaml: + file: alerting/team2/rules.yaml + team3-alert-rules.yaml: + file: alerting/team3/rules.yaml + notification-policies.yaml: + file: alerting/shared/notification-policies.yaml + notification-templates.yaml: + file: alerting/shared/notification-templates.yaml + contactpoints.yaml: + apiVersion: 1 + contactPoints: + - orgId: 1 + name: Slack channel + receivers: + - uid: default-receiver + type: slack + settings: + # Webhook URL to be filled in + url: "" + # We need to escape double curly braces for the tpl function. + text: '{{ `{{ template "default.message" . }}` }}' + title: '{{ `{{ template "default.title" . }}` }}' +``` + +The two possibilities for static alerting resource provisioning are: + +* Inlining the file contents as shown for contact points in the above example. +* Importing a file using a relative path starting from the chart root directory as shown for the alert rules in the above example. + +### Important notes on file provisioning + +* The format of the files is defined in the [Grafana documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/) on file provisioning. +* The chart supports importing YAML and JSON files. +* The filename must be unique, otherwise one volume mount will overwrite the other. +* In case of inlining, double curly braces that arise from the Grafana configuration format and are not intended as templates for the chart must be escaped. +* The number of total files under `alerting:` is not limited. Each file will end up as a volume mount in the corresponding provisioning folder of the deployed Grafana instance. +* The file size for each import is limited by what the function `.Files.Get` can handle, which suffices for most cases. + +## How to serve Grafana with a path prefix (/grafana) + +In order to serve Grafana with a prefix (e.g., ), add the following to your values.yaml. + +```yaml +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/rewrite-target: /$1 + nginx.ingress.kubernetes.io/use-regex: "true" + + path: /grafana/?(.*) + hosts: + - k8s.example.dev + +grafana.ini: + server: + root_url: http://localhost:3000/grafana # this host can be localhost +``` + +## How to securely reference secrets in grafana.ini + +This example uses Grafana [file providers](https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider) for secret values and the `extraSecretMounts` configuration flag (Additional grafana server secret mounts) to mount the secrets. + +In grafana.ini: + +```yaml +grafana.ini: + [auth.generic_oauth] + enabled = true + client_id = $__file{/etc/secrets/auth_generic_oauth/client_id} + client_secret = $__file{/etc/secrets/auth_generic_oauth/client_secret} +``` + +Existing secret, or created along with helm: + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: auth-generic-oauth-secret +type: Opaque +stringData: + client_id: + client_secret: +``` + +Include in the `extraSecretMounts` configuration flag: + +```yaml +- extraSecretMounts: + - name: auth-generic-oauth-secret-mount + secretName: auth-generic-oauth-secret + defaultMode: 0440 + mountPath: /etc/secrets/auth_generic_oauth + readOnly: true +``` + +### extraSecretMounts using a Container Storage Interface (CSI) provider + +This example uses a CSI driver e.g. retrieving secrets using [Azure Key Vault Provider](https://github.com/Azure/secrets-store-csi-driver-provider-azure) + +```yaml +- extraSecretMounts: + - name: secrets-store-inline + mountPath: /run/secrets + readOnly: true + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: "my-provider" + nodePublishSecretRef: + name: akv-creds +``` + +## Image Renderer Plug-In + +This chart supports enabling [remote image rendering](https://github.com/grafana/grafana-image-renderer/blob/master/README.md#run-in-docker) + +```yaml +imageRenderer: + enabled: true +``` + +### Image Renderer NetworkPolicy + +By default the image-renderer pods will have a network policy which only allows ingress traffic from the created grafana instance + +### High Availability for unified alerting + +If you want to run Grafana in a high availability cluster you need to enable +the headless service by setting `headlessService: true` in your `values.yaml` +file. + +As next step you have to setup the `grafana.ini` in your `values.yaml` in a way +that it will make use of the headless service to obtain all the IPs of the +cluster. You should replace ``{{ Name }}`` with the name of your helm deployment. + +```yaml +grafana.ini: + ... + unified_alerting: + enabled: true + ha_peers: {{ Name }}-headless:9094 + ha_listen_address: ${POD_IP}:9094 + ha_advertise_address: ${POD_IP}:9094 + + alerting: + enabled: false +``` diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/dashboards/custom-dashboard.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/dashboards/custom-dashboard.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/dashboards/custom-dashboard.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/NOTES.txt new file mode 100644 index 0000000000..a40f666a47 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/NOTES.txt @@ -0,0 +1,55 @@ +1. Get your '{{ .Values.adminUser }}' user password by running: + + kubectl get secret --namespace {{ include "grafana.namespace" . }} {{ .Values.admin.existingSecret | default (include "grafana.fullname" .) }} -o jsonpath="{.data.{{ .Values.admin.passwordKey | default "admin-password" }}}" | base64 --decode ; echo + + +2. The Grafana server can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster: + + {{ include "grafana.fullname" . }}.{{ include "grafana.namespace" . }}.svc.cluster.local +{{ if .Values.ingress.enabled }} + If you bind grafana to 80, please update values in values.yaml and reinstall: + ``` + securityContext: + runAsUser: 0 + runAsGroup: 0 + fsGroup: 0 + + command: + - "setcap" + - "'cap_net_bind_service=+ep'" + - "/usr/sbin/grafana-server &&" + - "sh" + - "/run.sh" + ``` + Details refer to https://grafana.com/docs/installation/configuration/#http-port. + Or grafana would always crash. + + From outside the cluster, the server URL(s) are: + {{- range .Values.ingress.hosts }} + http://{{ . }} + {{- end }} +{{- else }} + Get the Grafana URL to visit by running these commands in the same shell: + {{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ include "grafana.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "grafana.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ include "grafana.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo 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. + You can watch the status of by running 'kubectl get svc --namespace {{ include "grafana.namespace" . }} -w {{ include "grafana.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ include "grafana.namespace" . }} {{ include "grafana.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + http://$SERVICE_IP:{{ .Values.service.port -}} + {{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ include "grafana.namespace" . }} -l "app.kubernetes.io/name={{ include "grafana.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ include "grafana.namespace" . }} port-forward $POD_NAME 3000 + {{- end }} +{{- end }} + +3. Login with the password from step 1 and the username: {{ .Values.adminUser }} + +{{- if and (not .Values.persistence.enabled) (not .Values.persistence.disableWarning) }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Grafana pod is terminated. ##### +################################################################################# +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_config.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_config.tpl new file mode 100644 index 0000000000..b866217f2e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_config.tpl @@ -0,0 +1,172 @@ +{{/* + Generate config map data + */}} +{{- define "grafana.configData" -}} +{{ include "grafana.assertNoLeakedSecrets" . }} +{{- $files := .Files }} +{{- $root := . -}} +{{- with .Values.plugins }} +plugins: {{ join "," . }} +{{- end }} +grafana.ini: | +{{- range $elem, $elemVal := index .Values "grafana.ini" }} + {{- if not (kindIs "map" $elemVal) }} + {{- if kindIs "invalid" $elemVal }} + {{ $elem }} = + {{- else if kindIs "string" $elemVal }} + {{ $elem }} = {{ tpl $elemVal $ }} + {{- else }} + {{ $elem }} = {{ $elemVal }} + {{- end }} + {{- end }} +{{- end }} +{{- range $key, $value := index .Values "grafana.ini" }} + {{- if kindIs "map" $value }} + [{{ $key }}] + {{- range $elem, $elemVal := $value }} + {{- if kindIs "invalid" $elemVal }} + {{ $elem }} = + {{- else if kindIs "string" $elemVal }} + {{ $elem }} = {{ tpl $elemVal $ }} + {{- else }} + {{ $elem }} = {{ $elemVal }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- range $key, $value := .Values.datasources }} +{{- if not (hasKey $value "secret") }} +{{ $key }}: | + {{- tpl (toYaml $value | nindent 2) $root }} +{{- end }} +{{- end }} + +{{- range $key, $value := .Values.notifiers }} +{{- if not (hasKey $value "secret") }} +{{ $key }}: | + {{- toYaml $value | nindent 2 }} +{{- end }} +{{- end }} + +{{- range $key, $value := .Values.alerting }} +{{- if (hasKey $value "file") }} +{{ $key }}: +{{- toYaml ( $files.Get $value.file ) | nindent 2 }} +{{- else if (or (hasKey $value "secret") (hasKey $value "secretFile"))}} +{{/* will be stored inside secret generated by "configSecret.yaml"*/}} +{{- else }} +{{ $key }}: | + {{- tpl (toYaml $value | nindent 2) $root }} +{{- end }} +{{- end }} + +{{- range $key, $value := .Values.dashboardProviders }} +{{ $key }}: | + {{- toYaml $value | nindent 2 }} +{{- end }} + +{{- if .Values.dashboards }} +download_dashboards.sh: | + #!/usr/bin/env sh + set -euf + {{- if .Values.dashboardProviders }} + {{- range $key, $value := .Values.dashboardProviders }} + {{- range $value.providers }} + mkdir -p {{ .options.path }} + {{- end }} + {{- end }} + {{- end }} +{{ $dashboardProviders := .Values.dashboardProviders }} +{{- range $provider, $dashboards := .Values.dashboards }} + {{- range $key, $value := $dashboards }} + {{- if (or (hasKey $value "gnetId") (hasKey $value "url")) }} + curl -skf \ + --connect-timeout 60 \ + --max-time 60 \ + {{- if not $value.b64content }} + {{- if not $value.acceptHeader }} + -H "Accept: application/json" \ + {{- else }} + -H "Accept: {{ $value.acceptHeader }}" \ + {{- end }} + {{- if $value.token }} + -H "Authorization: token {{ $value.token }}" \ + {{- end }} + {{- if $value.bearerToken }} + -H "Authorization: Bearer {{ $value.bearerToken }}" \ + {{- end }} + {{- if $value.basic }} + -H "Authorization: Basic {{ $value.basic }}" \ + {{- end }} + {{- if $value.gitlabToken }} + -H "PRIVATE-TOKEN: {{ $value.gitlabToken }}" \ + {{- end }} + -H "Content-Type: application/json;charset=UTF-8" \ + {{- end }} + {{- $dpPath := "" -}} + {{- range $kd := (index $dashboardProviders "dashboardproviders.yaml").providers }} + {{- if eq $kd.name $provider }} + {{- $dpPath = $kd.options.path }} + {{- end }} + {{- end }} + {{- if $value.url }} + "{{ $value.url }}" \ + {{- else }} + "https://grafana.com/api/dashboards/{{ $value.gnetId }}/revisions/{{- if $value.revision -}}{{ $value.revision }}{{- else -}}1{{- end -}}/download" \ + {{- end }} + {{- if $value.datasource }} + {{- if kindIs "string" $value.datasource }} + | sed '/-- .* --/! s/"datasource":.*,/"datasource": "{{ $value.datasource }}",/g' \ + {{- end }} + {{- if kindIs "slice" $value.datasource }} + {{- range $value.datasource }} + | sed '/-- .* --/! s/${{"{"}}{{ .name }}}/{{ .value }}/g' \ + {{- end }} + {{- end }} + {{- end }} + {{- if $value.b64content }} + | base64 -d \ + {{- end }} + > "{{- if $dpPath -}}{{ $dpPath }}{{- else -}}/var/lib/grafana/dashboards/{{ $provider }}{{- end -}}/{{ $key }}.json" + {{ end }} + {{- end }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* + Generate dashboard json config map data + */}} +{{- define "grafana.configDashboardProviderData" -}} +provider.yaml: |- + apiVersion: 1 + providers: + - name: '{{ .Values.sidecar.dashboards.provider.name }}' + orgId: {{ .Values.sidecar.dashboards.provider.orgid }} + {{- if not .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} + folder: '{{ .Values.sidecar.dashboards.provider.folder }}' + folderUid: '{{ .Values.sidecar.dashboards.provider.folderUid }}' + {{- end }} + type: {{ .Values.sidecar.dashboards.provider.type }} + disableDeletion: {{ .Values.sidecar.dashboards.provider.disableDelete }} + allowUiUpdates: {{ .Values.sidecar.dashboards.provider.allowUiUpdates }} + updateIntervalSeconds: {{ .Values.sidecar.dashboards.provider.updateIntervalSeconds | default 30 }} + options: + foldersFromFilesStructure: {{ .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} + path: {{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }} +{{- end -}} + +{{- define "grafana.secretsData" -}} +{{- if and (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) }} +admin-user: {{ .Values.adminUser | b64enc | quote }} +{{- if .Values.adminPassword }} +admin-password: {{ .Values.adminPassword | b64enc | quote }} +{{- else }} +admin-password: {{ include "grafana.password" . }} +{{- end }} +{{- end }} +{{- if not .Values.ldap.existingSecret }} +ldap-toml: {{ tpl .Values.ldap.config $ | b64enc | quote }} +{{- end }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_helpers.tpl new file mode 100644 index 0000000000..68d2d815d8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_helpers.tpl @@ -0,0 +1,305 @@ +# Rancher +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "grafana.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 "grafana.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 "grafana.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create the name of the service account +*/}} +{{- define "grafana.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "grafana.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "grafana.serviceAccountNameTest" -}} +{{- if .Values.serviceAccount.create }} +{{- default (print (include "grafana.fullname" .) "-test") .Values.serviceAccount.nameTest }} +{{- else }} +{{- default "default" .Values.serviceAccount.nameTest }} +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "grafana.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "grafana.labels" -}} +helm.sh/chart: {{ include "grafana.chart" . }} +{{ include "grafana.selectorLabels" . }} +{{- if or .Chart.AppVersion .Values.image.tag }} +app.kubernetes.io/version: {{ mustRegexReplaceAllLiteral "@sha.*" .Values.image.tag "" | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Values.extraLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "grafana.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "grafana.imageRenderer.labels" -}} +helm.sh/chart: {{ include "grafana.chart" . }} +{{ include "grafana.imageRenderer.selectorLabels" . }} +{{- if or .Chart.AppVersion .Values.image.tag }} +app.kubernetes.io/version: {{ mustRegexReplaceAllLiteral "@sha.*" .Values.image.tag "" | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels ImageRenderer +*/}} +{{- define "grafana.imageRenderer.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Looks if there's an existing secret and reuse its password. If not it generates +new password and use it. +*/}} +{{- define "grafana.password" -}} +{{- $secret := (lookup "v1" "Secret" (include "grafana.namespace" .) (include "grafana.fullname" .) ) }} +{{- if $secret }} +{{- index $secret "data" "admin-password" }} +{{- else }} +{{- (randAlphaNum 40) | b64enc | quote }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for rbac. +*/}} +{{- define "grafana.rbac.apiVersion" -}} +{{- if $.Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }} +{{- print "rbac.authorization.k8s.io/v1" }} +{{- else }} +{{- print "rbac.authorization.k8s.io/v1beta1" }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "grafana.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 the appropriate apiVersion for Horizontal Pod Autoscaler. +*/}} +{{- define "grafana.hpa.apiVersion" -}} +{{- if .Capabilities.APIVersions.Has "autoscaling/v2" }} +{{- print "autoscaling/v2" }} +{{- else }} +{{- print "autoscaling/v2beta2" }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for podDisruptionBudget. +*/}} +{{- define "grafana.podDisruptionBudget.apiVersion" -}} +{{- if $.Values.podDisruptionBudget.apiVersion }} +{{- print $.Values.podDisruptionBudget.apiVersion }} +{{- else if $.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +{{- print "policy/v1" }} +{{- else }} +{{- print "policy/v1beta1" }} +{{- end }} +{{- end }} + +{{/* +Return if ingress is stable. +*/}} +{{- define "grafana.ingress.isStable" -}} +{{- eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1" }} +{{- end }} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "grafana.ingress.supportsIngressClassName" -}} +{{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} +{{- end }} + +{{/* +Return if ingress supports pathType. +*/}} +{{- define "grafana.ingress.supportsPathType" -}} +{{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} +{{- end }} + +{{/* +Formats imagePullSecrets. Input is (dict "root" . "imagePullSecrets" .{specific imagePullSecrets}) +*/}} +{{- define "grafana.imagePullSecrets" -}} +{{- $root := .root }} +{{- range (concat .root.Values.global.imagePullSecrets .imagePullSecrets) }} +{{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml (dict "name" (tpl .name $root)) | trim }} +{{- else }} +- name: {{ tpl . $root }} +{{- end }} +{{- end }} +{{- end }} + + +{{/* + Checks whether or not the configSecret secret has to be created + */}} +{{- define "grafana.shouldCreateConfigSecret" -}} +{{- $secretFound := false -}} +{{- range $key, $value := .Values.datasources }} + {{- if hasKey $value "secret" }} + {{- $secretFound = true}} + {{- end }} +{{- end }} +{{- range $key, $value := .Values.notifiers }} + {{- if hasKey $value "secret" }} + {{- $secretFound = true}} + {{- end }} +{{- end }} +{{- range $key, $value := .Values.alerting }} + {{- if (or (hasKey $value "secret") (hasKey $value "secretFile")) }} + {{- $secretFound = true}} + {{- end }} +{{- end }} +{{- $secretFound}} +{{- end -}} + +{{/* + Checks whether the user is attempting to store secrets in plaintext + in the grafana.ini configmap +*/}} +{{/* grafana.assertNoLeakedSecrets checks for sensitive keys in values */}} +{{- define "grafana.assertNoLeakedSecrets" -}} + {{- $sensitiveKeysYaml := ` +sensitiveKeys: +- path: ["database", "password"] +- path: ["smtp", "password"] +- path: ["security", "secret_key"] +- path: ["security", "admin_password"] +- path: ["auth.basic", "password"] +- path: ["auth.ldap", "bind_password"] +- path: ["auth.google", "client_secret"] +- path: ["auth.github", "client_secret"] +- path: ["auth.gitlab", "client_secret"] +- path: ["auth.generic_oauth", "client_secret"] +- path: ["auth.okta", "client_secret"] +- path: ["auth.azuread", "client_secret"] +- path: ["auth.grafana_com", "client_secret"] +- path: ["auth.grafananet", "client_secret"] +- path: ["azure", "user_identity_client_secret"] +- path: ["unified_alerting", "ha_redis_password"] +- path: ["metrics", "basic_auth_password"] +- path: ["external_image_storage.s3", "secret_key"] +- path: ["external_image_storage.webdav", "password"] +- path: ["external_image_storage.azure_blob", "account_key"] +` | fromYaml -}} + {{- if $.Values.assertNoLeakedSecrets -}} + {{- $grafanaIni := index .Values "grafana.ini" -}} + {{- range $_, $secret := $sensitiveKeysYaml.sensitiveKeys -}} + {{- $currentMap := $grafanaIni -}} + {{- $shouldContinue := true -}} + {{- range $index, $elem := $secret.path -}} + {{- if and $shouldContinue (hasKey $currentMap $elem) -}} + {{- if eq (len $secret.path) (add1 $index) -}} + {{- if not (regexMatch "\\$(?:__(?:env|file|vault))?{[^}]+}" (index $currentMap $elem)) -}} + {{- fail (printf "Sensitive key '%s' should not be defined explicitly in values. Use variable expansion instead. You can disable this client-side validation by changing the value of assertNoLeakedSecrets." (join "." $secret.path)) -}} + {{- end -}} + {{- else -}} + {{- $currentMap = index $currentMap $elem -}} + {{- end -}} + {{- else -}} + {{- $shouldContinue = false -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_pod.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_pod.tpl new file mode 100644 index 0000000000..44526e5239 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/_pod.tpl @@ -0,0 +1,1306 @@ +{{- define "grafana.pod" -}} +{{- $sts := list "sts" "StatefulSet" "statefulset" -}} +{{- $root := . -}} +{{- with .Values.schedulerName }} +schedulerName: "{{ . }}" +{{- end }} +serviceAccountName: {{ include "grafana.serviceAccountName" . }} +automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} +{{- with .Values.securityContext }} +securityContext: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- with .Values.hostAliases }} +hostAliases: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- if .Values.dnsPolicy }} +dnsPolicy: {{ .Values.dnsPolicy }} +{{- end }} +{{- with .Values.dnsConfig }} +dnsConfig: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- with .Values.priorityClassName }} +priorityClassName: {{ . }} +{{- end }} +{{- if ( or .Values.persistence.enabled .Values.dashboards .Values.extraInitContainers (and .Values.sidecar.alerts.enabled .Values.sidecar.alerts.initAlerts) (and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources) (and .Values.sidecar.notifiers.enabled .Values.sidecar.notifiers.initNotifiers)) }} +initContainers: +{{- end }} +{{- if ( and .Values.persistence.enabled .Values.initChownData.enabled ) }} + - name: init-chown-data + {{- $registry := include "system_default_registry" . | default .Values.initChownData.image.registry -}} + {{- if .Values.initChownData.image.sha }} + image: "{{ $registry }}{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}@sha256:{{ .Values.initChownData.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.initChownData.image.pullPolicy }} + {{- with .Values.initChownData.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + command: + - chown + - -R + - {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} + - /var/lib/grafana + {{- with .Values.initChownData.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: storage + mountPath: "/var/lib/grafana" + {{- with .Values.persistence.subPath }} + subPath: {{ tpl . $root }} + {{- end }} +{{- end }} +{{- if .Values.dashboards }} + - name: download-dashboards + {{- $registry := include "system_default_registry" . | default .Values.downloadDashboardsImage.registry -}} + {{- if .Values.downloadDashboardsImage.sha }} + image: "{{ $registry }}{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}@sha256:{{ .Values.downloadDashboardsImage.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.downloadDashboardsImage.pullPolicy }} + command: ["/bin/sh"] + args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh -x /etc/grafana/download_dashboards.sh" ] + {{- with .Values.downloadDashboards.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + env: + {{- range $key, $value := .Values.downloadDashboards.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- range $key, $value := .Values.downloadDashboards.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 10 }} + {{- end }} + {{- with .Values.downloadDashboards.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.downloadDashboards.envFromSecret }} + envFrom: + - secretRef: + name: {{ tpl . $root }} + {{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/download_dashboards.sh" + subPath: download_dashboards.sh + - name: storage + mountPath: "/var/lib/grafana" + {{- with .Values.persistence.subPath }} + subPath: {{ tpl . $root }} + {{- end }} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- end }} +{{- end }} +{{- if and .Values.sidecar.alerts.enabled .Values.sidecar.alerts.initAlerts }} + - name: {{ include "grafana.name" . }}-init-sc-alerts + {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} + {{- if .Values.sidecar.image.sha }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.alerts.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.alerts.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: "LIST" + - name: LABEL + value: "{{ .Values.sidecar.alerts.label }}" + {{- with .Values.sidecar.alerts.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/alerting" + - name: RESOURCE + value: {{ quote .Values.sidecar.alerts.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.alerts.searchNamespace }} + - name: NAMESPACE + value: {{ . | join "," | quote }} + {{- end }} + {{- with .Values.sidecar.alerts.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: {{ quote . }} + {{- end }} + {{- with .Values.sidecar.alerts.script }} + - name: SCRIPT + value: {{ quote . }} + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-alerts-volume + mountPath: "/etc/grafana/provisioning/alerting" + {{- with .Values.sidecar.alerts.extraMounts }} + {{- toYaml . | trim | nindent 6 }} + {{- end }} +{{- end }} +{{- if and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources }} + - name: {{ include "grafana.name" . }}-init-sc-datasources + {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} + {{- if .Values.sidecar.image.sha }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.datasources.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- range $key, $value := .Values.sidecar.datasources.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 10 }} + {{- end }} + {{- if .Values.sidecar.datasources.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: "LIST" + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + {{- with .Values.sidecar.datasources.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: {{ quote .Values.sidecar.datasources.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- if .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (.Values.sidecar.datasources.searchNamespace | join ",") . }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end }} +{{- if and .Values.sidecar.notifiers.enabled .Values.sidecar.notifiers.initNotifiers }} + - name: {{ include "grafana.name" . }}-init-sc-notifiers + {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} + {{- if .Values.sidecar.image.sha }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.notifiers.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.notifiers.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: LIST + - name: LABEL + value: "{{ .Values.sidecar.notifiers.label }}" + {{- with .Values.sidecar.notifiers.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/notifiers" + - name: RESOURCE + value: {{ quote .Values.sidecar.notifiers.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.notifiers.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" +{{- end}} +{{- with .Values.extraInitContainers }} + {{- tpl (toYaml .) $root | nindent 2 }} +{{- end }} +{{- if or .Values.image.pullSecrets .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- include "grafana.imagePullSecrets" (dict "root" $root "imagePullSecrets" .Values.image.pullSecrets) | nindent 2 }} +{{- end }} +{{- if not .Values.enableKubeBackwardCompatibility }} +enableServiceLinks: {{ .Values.enableServiceLinks }} +{{- end }} +containers: +{{- if and .Values.sidecar.alerts.enabled (not .Values.sidecar.alerts.initAlerts) }} + - name: {{ include "grafana.name" . }}-sc-alerts + {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} + {{- if .Values.sidecar.image.sha }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.alerts.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.alerts.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.alerts.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.alerts.label }}" + {{- with .Values.sidecar.alerts.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/alerting" + - name: RESOURCE + value: {{ quote .Values.sidecar.alerts.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.alerts.searchNamespace }} + - name: NAMESPACE + value: {{ . | join "," | quote }} + {{- end }} + {{- with .Values.sidecar.alerts.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: {{ quote . }} + {{- end }} + {{- with .Values.sidecar.alerts.script }} + - name: SCRIPT + value: {{ quote . }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.alerts.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.alerts.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.alerts.watchServerTimeout }} + {{- if ne .Values.sidecar.alerts.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.alerts.watchServerTimeout with .Values.sidecar.alerts.watchMethod %s" .Values.sidecar.alerts.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.alerts.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.alerts.watchClientTimeout }} + {{- if ne .Values.sidecar.alerts.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.alerts.watchClientTimeout with .Values.sidecar.alerts.watchMethod %s" .Values.sidecar.alerts.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.alerts.watchClientTimeout }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-alerts-volume + mountPath: "/etc/grafana/provisioning/alerting" + {{- with .Values.sidecar.alerts.extraMounts }} + {{- toYaml . | trim | nindent 6 }} + {{- end }} +{{- end}} +{{- if .Values.sidecar.dashboards.enabled }} + - name: {{ include "grafana.name" . }}-sc-dashboard + {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} + {{- if .Values.sidecar.image.sha }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.dashboards.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- range $key, $value := .Values.sidecar.dashboards.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 10 }} + {{- end }} + {{- if .Values.sidecar.dashboards.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.dashboards.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.dashboards.label }}" + {{- with .Values.sidecar.dashboards.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.dashboards.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.dashboards.logLevel }} + {{- end }} + - name: FOLDER + value: "{{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}" + - name: RESOURCE + value: {{ quote .Values.sidecar.dashboards.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.dashboards.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.dashboards.folderAnnotation }} + - name: FOLDER_ANNOTATION + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.dashboards.script }} + - name: SCRIPT + value: "{{ . }}" + {{- end }} + {{- if not .Values.sidecar.dashboards.skipReload }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + - name: REQ_URL + value: {{ .Values.sidecar.dashboards.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.dashboards.watchServerTimeout }} + {{- if ne .Values.sidecar.dashboards.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.dashboards.watchServerTimeout with .Values.sidecar.dashboards.watchMethod %s" .Values.sidecar.dashboards.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.dashboards.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.dashboards.watchClientTimeout }} + {{- if ne .Values.sidecar.dashboards.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.dashboards.watchClientTimeout with .Values.sidecar.dashboards.watchMethod %s" .Values.sidecar.dashboards.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: {{ .Values.sidecar.dashboards.watchClientTimeout | quote }} + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} + {{- with .Values.sidecar.dashboards.extraMounts }} + {{- toYaml . | trim | nindent 6 }} + {{- end }} +{{- end}} +{{- if and .Values.sidecar.datasources.enabled (not .Values.sidecar.datasources.initDatasources) }} + - name: {{ include "grafana.name" . }}-sc-datasources + {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} + {{- if .Values.sidecar.image.sha }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.datasources.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- range $key, $value := .Values.sidecar.datasources.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 10 }} + {{- end }} + {{- if .Values.sidecar.datasources.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.datasources.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + {{- with .Values.sidecar.datasources.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: {{ quote .Values.sidecar.datasources.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if .Values.sidecar.datasources.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.datasources.script }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.datasources.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.datasources.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.datasources.watchServerTimeout }} + {{- if ne .Values.sidecar.datasources.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.datasources.watchServerTimeout with .Values.sidecar.datasources.watchMethod %s" .Values.sidecar.datasources.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.datasources.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.datasources.watchClientTimeout }} + {{- if ne .Values.sidecar.datasources.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.datasources.watchClientTimeout with .Values.sidecar.datasources.watchMethod %s" .Values.sidecar.datasources.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.datasources.watchClientTimeout }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end}} +{{- if .Values.sidecar.notifiers.enabled }} + - name: {{ include "grafana.name" . }}-sc-notifiers + {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} + {{- if .Values.sidecar.image.sha }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.notifiers.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.notifiers.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.notifiers.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.notifiers.label }}" + {{- with .Values.sidecar.notifiers.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/notifiers" + - name: RESOURCE + value: {{ quote .Values.sidecar.notifiers.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- with .Values.sidecar.notifiers.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- if .Values.sidecar.notifiers.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.notifiers.script }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.notifiers.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.notifiers.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.notifiers.watchServerTimeout }} + {{- if ne .Values.sidecar.notifiers.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.notifiers.watchServerTimeout with .Values.sidecar.notifiers.watchMethod %s" .Values.sidecar.notifiers.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.notifiers.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.notifiers.watchClientTimeout }} + {{- if ne .Values.sidecar.notifiers.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.notifiers.watchClientTimeout with .Values.sidecar.notifiers.watchMethod %s" .Values.sidecar.notifiers.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.notifiers.watchClientTimeout }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" +{{- end}} +{{- if .Values.sidecar.plugins.enabled }} + - name: {{ include "grafana.name" . }}-sc-plugins + {{- $registry := include "system_default_registry" . | default .Values.sidecar.image.registry -}} + {{- if .Values.sidecar.image.sha }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.plugins.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.plugins.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.plugins.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.plugins.label }}" + {{- if .Values.sidecar.plugins.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.plugins.labelValue }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.plugins.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.plugins.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/plugins" + - name: RESOURCE + value: {{ quote .Values.sidecar.plugins.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.plugins.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- with .Values.sidecar.plugins.script }} + - name: SCRIPT + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.plugins.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.plugins.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.plugins.watchServerTimeout }} + {{- if ne .Values.sidecar.plugins.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.plugins.watchServerTimeout with .Values.sidecar.plugins.watchMethod %s" .Values.sidecar.plugins.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.plugins.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.plugins.watchClientTimeout }} + {{- if ne .Values.sidecar.plugins.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.plugins.watchClientTimeout with .Values.sidecar.plugins.watchMethod %s" .Values.sidecar.plugins.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.plugins.watchClientTimeout }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-plugins-volume + mountPath: "/etc/grafana/provisioning/plugins" +{{- end}} + - name: {{ .Chart.Name }} + {{- $registry := include "system_default_registry" . | default .Values.image.registry -}} + {{- if .Values.image.sha }} + image: "{{ $registry }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.command }} + command: + {{- range .Values.command }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- if .Values.args }} + args: + {{- range .Values.args }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/grafana.ini" + subPath: grafana.ini + {{- if .Values.ldap.enabled }} + - name: ldap + mountPath: "/etc/grafana/ldap.toml" + subPath: ldap.toml + {{- end }} + {{- range .Values.extraConfigmapMounts }} + - name: {{ tpl .name $root }} + mountPath: {{ tpl .mountPath $root }} + subPath: {{ tpl (.subPath | default "") $root }} + readOnly: {{ .readOnly }} + {{- end }} + - name: storage + mountPath: "/var/lib/grafana" + {{- with .Values.persistence.subPath }} + subPath: {{ tpl . $root }} + {{- end }} + {{- with .Values.dashboards }} + {{- range $provider, $dashboards := . }} + {{- range $key, $value := $dashboards }} + {{- if (or (hasKey $value "json") (hasKey $value "file")) }} + - name: dashboards-{{ $provider }} + mountPath: "/var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json" + subPath: "{{ $key }}.json" + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.dashboardsConfigMaps }} + {{- range (keys . | sortAlpha) }} + - name: dashboards-{{ . }} + mountPath: "/var/lib/grafana/dashboards/{{ . }}" + {{- end }} + {{- end }} + {{- with .Values.datasources }} + {{- $datasources := . }} + {{- range (keys . | sortAlpha) }} + {{- if (or (hasKey (index $datasources .) "secret")) }} {{/*check if current datasource should be handeled as secret */}} + - name: config-secret + mountPath: "/etc/grafana/provisioning/datasources/{{ . }}" + subPath: {{ . | quote }} + {{- else }} + - name: config + mountPath: "/etc/grafana/provisioning/datasources/{{ . }}" + subPath: {{ . | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.notifiers }} + {{- $notifiers := . }} + {{- range (keys . | sortAlpha) }} + {{- if (or (hasKey (index $notifiers .) "secret")) }} {{/*check if current notifier should be handeled as secret */}} + - name: config-secret + mountPath: "/etc/grafana/provisioning/notifiers/{{ . }}" + subPath: {{ . | quote }} + {{- else }} + - name: config + mountPath: "/etc/grafana/provisioning/notifiers/{{ . }}" + subPath: {{ . | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.alerting }} + {{- $alertingmap := .}} + {{- range (keys . | sortAlpha) }} + {{- if (or (hasKey (index $.Values.alerting .) "secret") (hasKey (index $.Values.alerting .) "secretFile")) }} {{/*check if current alerting entry should be handeled as secret */}} + - name: config-secret + mountPath: "/etc/grafana/provisioning/alerting/{{ . }}" + subPath: {{ . | quote }} + {{- else }} + - name: config + mountPath: "/etc/grafana/provisioning/alerting/{{ . }}" + subPath: {{ . | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.dashboardProviders }} + {{- range (keys . | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/dashboards/{{ . }}" + subPath: {{ . | quote }} + {{- end }} + {{- end }} + {{- with .Values.sidecar.alerts.enabled }} + - name: sc-alerts-volume + mountPath: "/etc/grafana/provisioning/alerting" + {{- end}} + {{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} + {{- if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + mountPath: "/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml" + subPath: provider.yaml + {{- end}} + {{- end}} + {{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" + {{- end}} + {{- if .Values.sidecar.plugins.enabled }} + - name: sc-plugins-volume + mountPath: "/etc/grafana/provisioning/plugins" + {{- end}} + {{- if .Values.sidecar.notifiers.enabled }} + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" + {{- end}} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + subPath: {{ .subPath | default "" }} + {{- end }} + {{- range .Values.extraVolumeMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + ports: + - name: {{ .Values.podPortName }} + containerPort: {{ .Values.service.targetPort }} + protocol: TCP + - name: {{ .Values.gossipPortName }}-tcp + containerPort: 9094 + protocol: TCP + - name: {{ .Values.gossipPortName }}-udp + containerPort: 9094 + protocol: UDP + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: GF_SECURITY_ADMIN_USER + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: GF_SECURITY_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if .Values.plugins }} + - name: GF_INSTALL_PLUGINS + valueFrom: + configMapKeyRef: + name: {{ include "grafana.fullname" . }} + key: plugins + {{- end }} + {{- if .Values.smtp.existingSecret }} + - name: GF_SMTP_USER + valueFrom: + secretKeyRef: + name: {{ .Values.smtp.existingSecret }} + key: {{ .Values.smtp.userKey | default "user" }} + - name: GF_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.smtp.existingSecret }} + key: {{ .Values.smtp.passwordKey | default "password" }} + {{- end }} + {{- if .Values.imageRenderer.enabled }} + - name: GF_RENDERING_SERVER_URL + value: http://{{ include "grafana.fullname" . }}-image-renderer.{{ include "grafana.namespace" . }}:{{ .Values.imageRenderer.service.port }}/render + - name: GF_RENDERING_CALLBACK_URL + value: {{ .Values.imageRenderer.grafanaProtocol }}://{{ include "grafana.fullname" . }}.{{ include "grafana.namespace" . }}:{{ .Values.service.port }}/{{ .Values.imageRenderer.grafanaSubPath }} + {{- end }} + - name: GF_PATHS_DATA + value: {{ (get .Values "grafana.ini").paths.data }} + - name: GF_PATHS_LOGS + value: {{ (get .Values "grafana.ini").paths.logs }} + - name: GF_PATHS_PLUGINS + value: {{ (get .Values "grafana.ini").paths.plugins }} + - name: GF_PATHS_PROVISIONING + value: {{ (get .Values "grafana.ini").paths.provisioning }} + {{- range $key, $value := .Values.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 10 }} + {{- end }} + {{- range $key, $value := .Values.env }} + - name: "{{ tpl $key $ }}" + value: "{{ tpl (print $value) $ }}" + {{- end }} + {{- if or .Values.envFromSecret (or .Values.envRenderSecret .Values.envFromSecrets) .Values.envFromConfigMaps }} + envFrom: + {{- if .Values.envFromSecret }} + - secretRef: + name: {{ tpl .Values.envFromSecret . }} + {{- end }} + {{- if .Values.envRenderSecret }} + - secretRef: + name: {{ include "grafana.fullname" . }}-env + {{- end }} + {{- range .Values.envFromSecrets }} + - secretRef: + name: {{ tpl .name $ }} + optional: {{ .optional | default false }} + {{- if .prefix }} + prefix: {{ tpl .prefix $ }} + {{- end }} + {{- end }} + {{- range .Values.envFromConfigMaps }} + - configMapRef: + name: {{ tpl .name $ }} + optional: {{ .optional | default false }} + {{- if .prefix }} + prefix: {{ tpl .prefix $ }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.lifecycleHooks }} + lifecycle: + {{- tpl (toYaml .) $root | nindent 6 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- with .Values.extraContainers }} + {{- tpl . $ | nindent 2 }} +{{- end }} +nodeSelector: {{ include "linux-node-selector" . | nindent 2 }} +{{- with .Values.nodeSelector }} + {{- toYaml . | nindent 2 }} +{{- end }} +{{- with .Values.affinity }} +affinity: + {{- tpl (toYaml .) $root | nindent 2 }} +{{- end }} +{{- with .Values.topologySpreadConstraints }} +topologySpreadConstraints: + {{- toYaml . | nindent 2 }} +{{- end }} +tolerations: {{ include "linux-node-tolerations" . | nindent 2 }} +{{- with .Values.tolerations }} + {{- toYaml . | nindent 2 }} +{{- end }} +volumes: + - name: config + configMap: + name: {{ include "grafana.fullname" . }} + {{- $createConfigSecret := eq (include "grafana.shouldCreateConfigSecret" .) "true" -}} + {{- if and .Values.createConfigmap $createConfigSecret }} + - name: config-secret + secret: + secretName: {{ include "grafana.fullname" . }}-config-secret + {{- end }} + {{- range .Values.extraConfigmapMounts }} + - name: {{ tpl .name $root }} + configMap: + name: {{ tpl .configMap $root }} + {{- with .items }} + items: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- if .Values.dashboards }} + {{- range (keys .Values.dashboards | sortAlpha) }} + - name: dashboards-{{ . }} + configMap: + name: {{ include "grafana.fullname" $ }}-dashboards-{{ . }} + {{- end }} + {{- end }} + {{- if .Values.dashboardsConfigMaps }} + {{- range $provider, $name := .Values.dashboardsConfigMaps }} + - name: dashboards-{{ $provider }} + configMap: + name: {{ tpl $name $root }} + {{- end }} + {{- end }} + {{- if .Values.ldap.enabled }} + - name: ldap + secret: + {{- if .Values.ldap.existingSecret }} + secretName: {{ .Values.ldap.existingSecret }} + {{- else }} + secretName: {{ include "grafana.fullname" . }} + {{- end }} + items: + - key: ldap-toml + path: ldap.toml + {{- end }} + {{- if and .Values.persistence.enabled (eq .Values.persistence.type "pvc") }} + - name: storage + persistentVolumeClaim: + claimName: {{ tpl (.Values.persistence.existingClaim | default (include "grafana.fullname" .)) . }} + {{- else if and .Values.persistence.enabled (has .Values.persistence.type $sts) }} + {{/* nothing */}} + {{- else }} + - name: storage + {{- if .Values.persistence.inMemory.enabled }} + emptyDir: + medium: Memory + {{- with .Values.persistence.inMemory.sizeLimit }} + sizeLimit: {{ . }} + {{- end }} + {{- else }} + emptyDir: {} + {{- end }} + {{- end }} + {{- if .Values.sidecar.alerts.enabled }} + - name: sc-alerts-volume + emptyDir: + {{- with .Values.sidecar.alerts.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- end }} + {{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume + emptyDir: + {{- with .Values.sidecar.dashboards.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + configMap: + name: {{ include "grafana.fullname" . }}-config-dashboards + {{- end }} + {{- end }} + {{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume + emptyDir: + {{- with .Values.sidecar.datasources.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- end }} + {{- if .Values.sidecar.plugins.enabled }} + - name: sc-plugins-volume + emptyDir: + {{- with .Values.sidecar.plugins.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- end }} + {{- if .Values.sidecar.notifiers.enabled }} + - name: sc-notifiers-volume + emptyDir: + {{- with .Values.sidecar.notifiers.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- end }} + {{- range .Values.extraSecretMounts }} + {{- if .secretName }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + defaultMode: {{ .defaultMode }} + {{- with .items }} + items: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- else if .projected }} + - name: {{ .name }} + projected: + {{- toYaml .projected | nindent 6 }} + {{- else if .csi }} + - name: {{ .name }} + csi: + {{- toYaml .csi | nindent 6 }} + {{- end }} + {{- end }} + {{- range .Values.extraVolumes }} + - name: {{ .name }} + {{- if .existingClaim }} + persistentVolumeClaim: + claimName: {{ .existingClaim }} + {{- else if .hostPath }} + hostPath: + {{ toYaml .hostPath | nindent 6 }} + {{- else if .csi }} + csi: + {{- toYaml .csi | nindent 6 }} + {{- else if .configMap }} + configMap: + {{- toYaml .configMap | nindent 6 }} + {{- else if .emptyDir }} + emptyDir: + {{- toYaml .emptyDir | nindent 6 }} + {{- else }} + emptyDir: {} + {{- end }} + {{- end }} + {{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + emptyDir: {} + {{- end }} + {{- with .Values.extraContainerVolumes }} + {{- tpl (toYaml .) $root | nindent 2 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/clusterrole.yaml new file mode 100644 index 0000000000..3af4b62b63 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/clusterrole.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.rbac.create (or (not .Values.rbac.namespaced) .Values.rbac.extraClusterRoleRules) (not .Values.rbac.useExistingClusterRole) }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "grafana.fullname" . }}-clusterrole +{{- if or .Values.sidecar.dashboards.enabled .Values.rbac.extraClusterRoleRules .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled .Values.sidecar.alerts.enabled }} +rules: + {{- if or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled .Values.sidecar.alerts.enabled }} + - apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] + {{- end}} + {{- with .Values.rbac.extraClusterRoleRules }} + {{- toYaml . | nindent 2 }} + {{- end}} +{{- else }} +rules: [] +{{- end}} +{{- end}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..bda9431a2c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/clusterrolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.rbac.create (or (not .Values.rbac.namespaced) .Values.rbac.extraClusterRoleRules) }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "grafana.fullname" . }}-clusterrolebinding + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ include "grafana.serviceAccountName" . }} + namespace: {{ include "grafana.namespace" . }} +roleRef: + kind: ClusterRole + {{- if .Values.rbac.useExistingClusterRole }} + name: {{ .Values.rbac.useExistingClusterRole }} + {{- else }} + name: {{ include "grafana.fullname" . }}-clusterrole + {{- end }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configSecret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configSecret.yaml new file mode 100644 index 0000000000..55574b9bbc --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configSecret.yaml @@ -0,0 +1,43 @@ +{{- $createConfigSecret := eq (include "grafana.shouldCreateConfigSecret" .) "true" -}} +{{- if and .Values.createConfigmap $createConfigSecret }} +{{- $files := .Files }} +{{- $root := . -}} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ include "grafana.fullname" . }}-config-secret" + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: +{{- range $key, $value := .Values.alerting }} + {{- if (hasKey $value "secretFile") }} + {{- $key | nindent 2 }}: + {{- toYaml ( $files.Get $value.secretFile ) | b64enc | nindent 4}} + {{/* as of https://helm.sh/docs/chart_template_guide/accessing_files/ this will only work if you fork this chart and add files to it*/}} + {{- end }} +{{- end }} +stringData: +{{- range $key, $value := .Values.datasources }} +{{- if (hasKey $value "secret") }} +{{- $key | nindent 2 }}: | + {{- tpl (toYaml $value.secret | nindent 4) $root }} +{{- end }} +{{- end }} +{{- range $key, $value := .Values.notifiers }} +{{- if (hasKey $value "secret") }} +{{- $key | nindent 2 }}: | + {{- tpl (toYaml $value.secret | nindent 4) $root }} +{{- end }} +{{- end }} +{{- range $key, $value := .Values.alerting }} +{{ if (hasKey $value "secret") }} + {{- $key | nindent 2 }}: | + {{- tpl (toYaml $value.secret | nindent 4) $root }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configmap-dashboard-provider.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configmap-dashboard-provider.yaml new file mode 100644 index 0000000000..b412c4d1f0 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configmap-dashboard-provider.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.sidecar.dashboards.enabled .Values.sidecar.dashboards.SCProvider }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "grafana.fullname" . }}-config-dashboards + namespace: {{ include "grafana.namespace" . }} +data: + {{- include "grafana.configDashboardProviderData" . | nindent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configmap.yaml new file mode 100644 index 0000000000..0a2edf47e3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/configmap.yaml @@ -0,0 +1,20 @@ +{{- if .Values.createConfigmap }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- if or .Values.configMapAnnotations .Values.annotations }} + annotations: + {{- with .Values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.configMapAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +data: + {{- include "grafana.configData" . | nindent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/dashboards-json-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/dashboards-json-configmap.yaml new file mode 100644 index 0000000000..b96ce72026 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/dashboards-json-configmap.yaml @@ -0,0 +1,38 @@ +{{- if .Values.dashboards }} +{{ $files := .Files }} +{{- range $provider, $dashboards := .Values.dashboards }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "grafana.fullname" $ }}-dashboards-{{ $provider }} + namespace: {{ include "grafana.namespace" $ }} + labels: + {{- include "grafana.labels" $ | nindent 4 }} + dashboard-provider: {{ $provider }} + {{- if $.Values.sidecar.dashboards.enabled }} + {{ $.Values.sidecar.dashboards.label }}: {{ $.Values.sidecar.dashboards.labelValue | quote }} + {{- end }} +{{- if $dashboards }} +data: +{{- $dashboardFound := false }} +{{- range $key, $value := $dashboards }} +{{- if (or (hasKey $value "json") (hasKey $value "file")) }} +{{- $dashboardFound = true }} + {{- print $key | nindent 2 }}.json: + {{- if hasKey $value "json" }} + |- + {{- $value.json | nindent 6 }} + {{- end }} + {{- if hasKey $value "file" }} + {{- toYaml ( $files.Get $value.file ) | nindent 4}} + {{- end }} +{{- end }} +{{- end }} +{{- if not $dashboardFound }} + {} +{{- end }} +{{- end }} +--- +{{- end }} + +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/deployment.yaml new file mode 100644 index 0000000000..46c016faa3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/deployment.yaml @@ -0,0 +1,53 @@ +{{- if (and (not .Values.useStatefulSet) (or (not .Values.persistence.enabled) (eq .Values.persistence.type "pvc"))) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and (not .Values.autoscaling.enabled) (.Values.replicas) }} + replicas: {{ .Values.replicas }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + {{- with .Values.deploymentStrategy }} + strategy: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include "grafana.configData" . | sha256sum }} + {{- if .Values.dashboards }} + checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} + {{- end }} + checksum/sc-dashboard-provider-config: {{ include "grafana.configDashboardProviderData" . | sha256sum }} + {{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + checksum/secret: {{ include "grafana.secretsData" . | sha256sum }} + {{- end }} + {{- if .Values.envRenderSecret }} + checksum/secret-env: {{ tpl (toYaml .Values.envRenderSecret) . | sha256sum }} + {{- end }} + kubectl.kubernetes.io/default-container: {{ .Chart.Name }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/extra-manifests.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/extra-manifests.yaml new file mode 100644 index 0000000000..a9bb3b6ba8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/headless-service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/headless-service.yaml new file mode 100644 index 0000000000..3028589d32 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/headless-service.yaml @@ -0,0 +1,22 @@ +{{- $sts := list "sts" "StatefulSet" "statefulset" -}} +{{- if or .Values.headlessService (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (has .Values.persistence.type $sts)) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grafana.fullname" . }}-headless + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + clusterIP: None + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} + type: ClusterIP + ports: + - name: {{ .Values.gossipPortName }}-tcp + port: 9094 +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/hpa.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/hpa.yaml new file mode 100644 index 0000000000..46bbcb49a2 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/hpa.yaml @@ -0,0 +1,52 @@ +{{- $sts := list "sts" "StatefulSet" "statefulset" -}} +{{- if .Values.autoscaling.enabled }} +apiVersion: {{ include "grafana.hpa.apiVersion" . }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "grafana.name" . }} + helm.sh/chart: {{ include "grafana.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + {{- if has .Values.persistence.type $sts }} + kind: StatefulSet + {{- else }} + kind: Deployment + {{- end }} + name: {{ include "grafana.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetMemory }} + - type: Resource + resource: + name: memory + {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ .Values.autoscaling.targetMemory }} + {{- else }} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemory }} + {{- end }} + {{- end }} + {{- if .Values.autoscaling.targetCPU }} + - type: Resource + resource: + name: cpu + {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ .Values.autoscaling.targetCPU }} + {{- else }} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPU }} + {{- end }} + {{- end }} + {{- if .Values.autoscaling.behavior }} + behavior: {{ toYaml .Values.autoscaling.behavior | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-deployment.yaml new file mode 100644 index 0000000000..acf03e4da4 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-deployment.yaml @@ -0,0 +1,199 @@ +{{ if .Values.imageRenderer.enabled }} +{{- $root := . -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} + {{- with .Values.imageRenderer.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.imageRenderer.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and (not .Values.imageRenderer.autoscaling.enabled) (.Values.imageRenderer.replicas) }} + replicas: {{ .Values.imageRenderer.replicas }} + {{- end }} + revisionHistoryLimit: {{ .Values.imageRenderer.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + + {{- with .Values.imageRenderer.deploymentStrategy }} + strategy: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 8 }} + {{- with .Values.imageRenderer.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.imageRenderer.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imageRenderer.schedulerName }} + schedulerName: "{{ . }}" + {{- end }} + {{- with .Values.imageRenderer.serviceAccountName }} + serviceAccountName: "{{ . }}" + {{- end }} + {{- with .Values.imageRenderer.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imageRenderer.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imageRenderer.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.imageRenderer.image.pullSecrets }} + imagePullSecrets: + {{- range . }} + - name: {{ tpl . $root }} + {{- end}} + {{- end }} + containers: + - name: {{ .Chart.Name }}-image-renderer + {{- $registry := include "system_default_registry" | default .Values.imageRenderer.image.registry -}} + {{- if .Values.imageRenderer.image.sha }} + image: "{{ $registry }}{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}@sha256:{{ .Values.imageRenderer.image.sha }}" + {{- else }} + image: "{{ $registry }}{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.imageRenderer.image.pullPolicy }} + {{- if .Values.imageRenderer.command }} + command: + {{- range .Values.imageRenderer.command }} + - {{ . }} + {{- end }} + {{- end}} + ports: + - name: {{ .Values.imageRenderer.service.portName }} + containerPort: {{ .Values.imageRenderer.service.targetPort }} + protocol: TCP + livenessProbe: + httpGet: + path: / + port: {{ .Values.imageRenderer.service.portName }} + env: + - name: HTTP_PORT + value: {{ .Values.imageRenderer.service.targetPort | quote }} + {{- if .Values.imageRenderer.serviceMonitor.enabled }} + - name: ENABLE_METRICS + value: "true" + {{- end }} + {{- range $key, $value := .Values.imageRenderer.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 16 }} + {{- end }} + {{- range $key, $value := .Values.imageRenderer.env }} + - name: {{ $key | quote }} + value: {{ $value | quote }} + {{- end }} + {{- with .Values.imageRenderer.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: /tmp + name: image-renderer-tmpfs + {{- range .Values.imageRenderer.extraConfigmapMounts }} + - name: {{ tpl .name $root }} + mountPath: {{ tpl .mountPath $root }} + subPath: {{ tpl (.subPath | default "") $root }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.imageRenderer.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + subPath: {{ .subPath | default "" }} + {{- end }} + {{- range .Values.imageRenderer.extraVolumeMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + {{- with .Values.imageRenderer.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.imageRenderer.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imageRenderer.affinity }} + affinity: + {{- tpl (toYaml .) $root | nindent 8 }} + {{- end }} + {{- with .Values.imageRenderer.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: image-renderer-tmpfs + emptyDir: {} + {{- range .Values.imageRenderer.extraConfigmapMounts }} + - name: {{ tpl .name $root }} + configMap: + name: {{ tpl .configMap $root }} + {{- with .items }} + items: + {{- toYaml . | nindent 14 }} + {{- end }} + {{- end }} + {{- range .Values.imageRenderer.extraSecretMounts }} + {{- if .secretName }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + defaultMode: {{ .defaultMode }} + {{- with .items }} + items: + {{- toYaml . | nindent 14 }} + {{- end }} + {{- else if .projected }} + - name: {{ .name }} + projected: + {{- toYaml .projected | nindent 12 }} + {{- else if .csi }} + - name: {{ .name }} + csi: + {{- toYaml .csi | nindent 12 }} + {{- end }} + {{- end }} + {{- range .Values.imageRenderer.extraVolumes }} + - name: {{ .name }} + {{- if .existingClaim }} + persistentVolumeClaim: + claimName: {{ .existingClaim }} + {{- else if .hostPath }} + hostPath: + {{ toYaml .hostPath | nindent 12 }} + {{- else if .csi }} + csi: + {{- toYaml .csi | nindent 12 }} + {{- else if .configMap }} + configMap: + {{- toYaml .configMap | nindent 12 }} + {{- else if .emptyDir }} + emptyDir: + {{- toYaml .emptyDir | nindent 12 }} + {{- else }} + emptyDir: {} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-hpa.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-hpa.yaml new file mode 100644 index 0000000000..b0f0059b79 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-hpa.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.autoscaling.enabled }} +apiVersion: {{ include "grafana.hpa.apiVersion" . }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer + namespace: {{ include "grafana.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer + helm.sh/chart: {{ include "grafana.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "grafana.fullname" . }}-image-renderer + minReplicas: {{ .Values.imageRenderer.autoscaling.minReplicas }} + maxReplicas: {{ .Values.imageRenderer.autoscaling.maxReplicas }} + metrics: + {{- if .Values.imageRenderer.autoscaling.targetMemory }} + - type: Resource + resource: + name: memory + {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ .Values.imageRenderer.autoscaling.targetMemory }} + {{- else }} + target: + type: Utilization + averageUtilization: {{ .Values.imageRenderer.autoscaling.targetMemory }} + {{- end }} + {{- end }} + {{- if .Values.imageRenderer.autoscaling.targetCPU }} + - type: Resource + resource: + name: cpu + {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ .Values.imageRenderer.autoscaling.targetCPU }} + {{- else }} + target: + type: Utilization + averageUtilization: {{ .Values.imageRenderer.autoscaling.targetCPU }} + {{- end }} + {{- end }} + {{- if .Values.imageRenderer.autoscaling.behavior }} + behavior: {{ toYaml .Values.imageRenderer.autoscaling.behavior | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-network-policy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-network-policy.yaml new file mode 100644 index 0000000000..bcbd24976c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-network-policy.yaml @@ -0,0 +1,79 @@ +{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.networkPolicy.limitIngress }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer-ingress + namespace: {{ include "grafana.namespace" . }} + annotations: + comment: Limit image-renderer ingress traffic from grafana +spec: + podSelector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + {{- with .Values.imageRenderer.podLabels }} + {{- toYaml . | nindent 6 }} + {{- end }} + + policyTypes: + - Ingress + ingress: + - ports: + - port: {{ .Values.imageRenderer.service.targetPort }} + protocol: TCP + from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "grafana.namespace" . }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 14 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 14 }} + {{- end }} + {{- with .Values.imageRenderer.networkPolicy.extraIngressSelectors -}} + {{ toYaml . | nindent 8 }} + {{- end }} +{{- end }} + +{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.networkPolicy.limitEgress }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer-egress + namespace: {{ include "grafana.namespace" . }} + annotations: + comment: Limit image-renderer egress traffic to grafana +spec: + podSelector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + {{- with .Values.imageRenderer.podLabels }} + {{- toYaml . | nindent 6 }} + {{- end }} + + policyTypes: + - Egress + egress: + # allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # talk only to grafana + - ports: + - port: {{ .Values.service.targetPort }} + protocol: TCP + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "grafana.namespace" . }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 14 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 14 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-service.yaml new file mode 100644 index 0000000000..f8da127cf8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-service.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} + {{- with .Values.imageRenderer.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.imageRenderer.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + {{- with .Values.imageRenderer.service.clusterIP }} + clusterIP: {{ . }} + {{- end }} + ports: + - name: {{ .Values.imageRenderer.service.portName }} + port: {{ .Values.imageRenderer.service.port }} + protocol: TCP + targetPort: {{ .Values.imageRenderer.service.targetPort }} + {{- with .Values.imageRenderer.appProtocol }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-servicemonitor.yaml new file mode 100644 index 0000000000..5d9f09d266 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/image-renderer-servicemonitor.yaml @@ -0,0 +1,48 @@ +{{- if .Values.imageRenderer.serviceMonitor.enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer + {{- if .Values.imageRenderer.serviceMonitor.namespace }} + namespace: {{ tpl .Values.imageRenderer.serviceMonitor.namespace . }} + {{- else }} + namespace: {{ include "grafana.namespace" . }} + {{- end }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} + {{- with .Values.imageRenderer.serviceMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.imageRenderer.service.portName }} + {{- with .Values.imageRenderer.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.imageRenderer.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + honorLabels: true + path: {{ .Values.imageRenderer.serviceMonitor.path }} + scheme: {{ .Values.imageRenderer.serviceMonitor.scheme }} + {{- with .Values.imageRenderer.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.imageRenderer.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + jobLabel: "{{ .Release.Name }}-image-renderer" + selector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ include "grafana.namespace" . }} + {{- with .Values.imageRenderer.serviceMonitor.targetLabels }} + targetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/ingress.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/ingress.yaml new file mode 100644 index 0000000000..b2ffd81095 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/ingress.yaml @@ -0,0 +1,78 @@ +{{- if .Values.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "grafana.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "grafana.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "grafana.ingress.supportsPathType" .) "true" -}} +{{- $fullName := include "grafana.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $ingressPathType := .Values.ingress.pathType -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +apiVersion: {{ include "grafana.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- 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 . $ | quote }} + 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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/networkpolicy.yaml new file mode 100644 index 0000000000..4cd3ed6976 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/networkpolicy.yaml @@ -0,0 +1,61 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + policyTypes: + {{- if .Values.networkPolicy.ingress }} + - Ingress + {{- end }} + {{- if .Values.networkPolicy.egress.enabled }} + - Egress + {{- end }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + + {{- if .Values.networkPolicy.egress.enabled }} + egress: + {{- if not .Values.networkPolicy.egress.blockDNSResolution }} + - ports: + - port: 53 + protocol: UDP + {{- end }} + - ports: + {{ .Values.networkPolicy.egress.ports | toJson }} + {{- with .Values.networkPolicy.egress.to }} + to: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.ingress }} + ingress: + - ports: + - port: {{ .Values.service.targetPort }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ include "grafana.fullname" . }}-client: "true" + {{- with .Values.networkPolicy.explicitNamespacesSelector }} + - namespaceSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + - podSelector: + matchLabels: + {{- include "grafana.labels" . | nindent 14 }} + role: read + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/nginx-config.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/nginx-config.yaml new file mode 100644 index 0000000000..557471f6ff --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/nginx-config.yaml @@ -0,0 +1,94 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-nginx-proxy-config + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +data: + nginx.conf: |- + worker_processes auto; + error_log /dev/stdout warn; + pid /var/cache/nginx/nginx.pid; + + events { + worker_connections 1024; + } + + http { + include /etc/nginx/mime.types; + log_format main '[$time_local - $status] $remote_addr - $remote_user $request ($http_referer)'; + + proxy_connect_timeout 10; + proxy_read_timeout 180; + proxy_send_timeout 5; + proxy_buffering off; + proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my_zone:100m inactive=1d max_size=10g; + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + server { + listen 8080; + access_log off; + + gzip on; + gzip_min_length 1k; + gzip_comp_level 2; + gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript image/jpeg image/gif image/png; + gzip_vary on; + gzip_disable "MSIE [1-6]\."; + + proxy_set_header Host $host; + + location /api/dashboards { + proxy_pass http://localhost:3000; + } + + location /api/search { + proxy_pass http://localhost:3000; + + sub_filter_types application/json; + sub_filter_once off; + } + + location /api/live/ { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $http_host; + proxy_pass http://localhost:3000; + } + + location / { + proxy_cache my_zone; + proxy_cache_valid 200 302 1d; + proxy_cache_valid 301 30d; + proxy_cache_valid any 5m; + proxy_cache_bypass $http_cache_control; + add_header X-Proxy-Cache $upstream_cache_status; + add_header Cache-Control "public"; + + proxy_pass http://localhost:3000/; + + sub_filter_once off; + + {{- if eq .Values.global.cattle.clusterId "local" -}} + sub_filter '"appSubUrl":""' '"appSubUrl":"/api/v1/namespaces/{{ template "grafana.namespace" . }}/services/http:{{ template "grafana.fullname" . }}:{{ .Values.service.port }}/proxy"'; + {{- else -}} + sub_filter '"appSubUrl":""' '"appSubUrl":"/k8s/clusters/{{ .Values.global.cattle.clusterId }}/api/v1/namespaces/{{ template "grafana.namespace" . }}/services/http:{{ template "grafana.fullname" . }}:{{ .Values.service.port }}/proxy"'; + {{- end -}} + + sub_filter ':"/avatar/' ':"avatar/'; + + if ($request_filename ~ .*\.(?:js|css|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$) { + expires 90d; + } + + rewrite ^/k8s/clusters/.*/proxy(.*) /$1 break; + + } + } + } diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/poddisruptionbudget.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..05251214ac --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/poddisruptionbudget.yaml @@ -0,0 +1,22 @@ +{{- if .Values.podDisruptionBudget }} +apiVersion: {{ include "grafana.podDisruptionBudget.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/podsecuritypolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000000..ebbdef5b5e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/podsecuritypolicy.yaml @@ -0,0 +1,45 @@ +{{- if and .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "grafana.fullname" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.rbac.pspAnnotations }} + annotations: {{ toYaml .Values.rbac.pspAnnotations | nindent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + # Default set from Docker, with DAC_OVERRIDE and CHOWN + - ALL + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'csi' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/pvc.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/pvc.yaml new file mode 100644 index 0000000000..b5fd5d4a3b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/pvc.yaml @@ -0,0 +1,41 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "pvc")}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.persistence.extraPvcLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.persistence.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.persistence.finalizers }} + finalizers: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + accessModes: +{{- $_ := required "Must provide at least one access mode for persistent volumes used by Grafana" .Values.persistence.accessModes }} +{{- $_ := required "Must provide at least one access mode for persistent volumes used by Grafana" (first .Values.persistence.accessModes) }} + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if and (.Values.persistence.lookupVolumeName) (lookup "v1" "PersistentVolumeClaim" (include "grafana.namespace" .) (include "grafana.fullname" .)) }} + volumeName: {{ (lookup "v1" "PersistentVolumeClaim" (include "grafana.namespace" .) (include "grafana.fullname" .)).spec.volumeName }} + {{- end }} + {{- with .Values.persistence.storageClassName }} + storageClassName: {{ . }} + {{- end }} + {{- with .Values.persistence.selectorLabels }} + selector: + matchLabels: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/role.yaml new file mode 100644 index 0000000000..4b5edd978c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/role.yaml @@ -0,0 +1,32 @@ +{{- if and .Values.rbac.create (not .Values.rbac.useExistingRole) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if or .Values.rbac.pspEnabled (and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled .Values.rbac.extraRoleRules)) }} +rules: + {{- if and .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ include "grafana.fullname" . }}] + {{- end }} + {{- if and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled) }} + - apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] + {{- end }} + {{- with .Values.rbac.extraRoleRules }} + {{- toYaml . | nindent 2 }} + {{- end}} +{{- else }} +rules: [] +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/rolebinding.yaml new file mode 100644 index 0000000000..58f77c6b0b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/rolebinding.yaml @@ -0,0 +1,25 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + {{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} + {{- else }} + name: {{ include "grafana.fullname" . }} + {{- end }} +subjects: +- kind: ServiceAccount + name: {{ include "grafana.serviceAccountName" . }} + namespace: {{ include "grafana.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/secret-env.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/secret-env.yaml new file mode 100644 index 0000000000..eb14aac707 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/secret-env.yaml @@ -0,0 +1,14 @@ +{{- if .Values.envRenderSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "grafana.fullname" . }}-env + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +type: Opaque +data: +{{- range $key, $val := .Values.envRenderSecret }} + {{ $key }}: {{ tpl ($val | toString) $ | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/secret.yaml new file mode 100644 index 0000000000..fd2ca50f4b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/secret.yaml @@ -0,0 +1,16 @@ +{{- if or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- include "grafana.secretsData" . | nindent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/service.yaml new file mode 100644 index 0000000000..022328c114 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/service.yaml @@ -0,0 +1,67 @@ +{{- if .Values.service.enabled }} +{{- $root := . }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.service.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $root }} + {{- end }} +spec: + {{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} + type: ClusterIP + {{- with .Values.service.clusterIP }} + clusterIP: {{ . }} + {{- end }} + {{- else if eq .Values.service.type "LoadBalancer" }} + type: LoadBalancer + {{- with .Values.service.loadBalancerIP }} + loadBalancerIP: {{ . }} + {{- end }} + {{- with .Values.service.loadBalancerClass }} + loadBalancerClass: {{ . }} + {{- end }} + {{- with .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- else }} + type: {{ .Values.service.type }} + {{- end }} + {{- if .Values.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.service.ipFamilies }} + ipFamilies: {{ .Values.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- with .Values.service.externalIPs }} + externalIPs: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ . }} + {{- end }} + ports: + - name: {{ .Values.service.portName }} + port: {{ .Values.service.port }} + protocol: TCP + targetPort: {{ .Values.service.targetPort }} + {{- with .Values.service.appProtocol }} + appProtocol: {{ . }} + {{- end }} + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + {{- with .Values.extraExposePorts }} + {{- tpl (toYaml . | nindent 4) $root }} + {{- end }} + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/serviceaccount.yaml new file mode 100644 index 0000000000..ffca0717ae --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.autoMount | default .Values.serviceAccount.automountServiceAccountToken }} +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} + name: {{ include "grafana.serviceAccountName" . }} + namespace: {{ include "grafana.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/servicemonitor.yaml new file mode 100644 index 0000000000..160a9c5562 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/servicemonitor.yaml @@ -0,0 +1,66 @@ +{{- if .Values.serviceMonitor.enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "grafana.fullname" . }} + {{- if .Values.serviceMonitor.namespace }} + namespace: {{ tpl .Values.serviceMonitor.namespace . }} + {{- else }} + namespace: {{ include "grafana.namespace" . }} + {{- end }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.serviceMonitor.labels }} + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.service.portName }} + {{- with .Values.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + honorLabels: true + path: {{ .Values.serviceMonitor.path }} + scheme: {{ .Values.serviceMonitor.scheme }} + {{- with .Values.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- end }} + metricRelabelings: + {{- if .Values.serviceMonitor.metricRelabelings }} + {{- toYaml .Values.serviceMonitor.metricRelabelings | nindent 6 }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName }} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + jobLabel: "{{ .Release.Name }}" + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ include "grafana.namespace" . }} + {{- with .Values.serviceMonitor.targetLabels }} + targetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/statefulset.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/statefulset.yaml new file mode 100644 index 0000000000..49278083e8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/statefulset.yaml @@ -0,0 +1,58 @@ +{{- $sts := list "sts" "StatefulSet" "statefulset" -}} +{{- if (or (.Values.useStatefulSet) (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (has .Values.persistence.type $sts)))}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + serviceName: {{ include "grafana.fullname" . }}-headless + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} + checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }} + {{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- end }} + kubectl.kubernetes.io/default-container: {{ .Chart.Name }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} + {{- if .Values.persistence.enabled}} + volumeClaimTemplates: + - metadata: + name: storage + spec: +{{- $_ := required "Must provide at least one access mode for persistent volumes used by Grafana" .Values.persistence.accessModes }} +{{- $_ := required "Must provide at least one access mode for persistent volumes used by Grafana" (first .Values.persistence.accessModes) }} + accessModes: {{ .Values.persistence.accessModes }} + storageClassName: {{ .Values.persistence.storageClassName }} + resources: + requests: + storage: {{ required "Must provide size for persistent volumes used by Grafana" .Values.persistence.size }} + {{- with .Values.persistence.selectorLabels }} + selector: + matchLabels: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-configmap.yaml new file mode 100644 index 0000000000..01c96c9243 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-configmap.yaml @@ -0,0 +1,20 @@ +{{- if .Values.testFramework.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "grafana.fullname" . }}-test + namespace: {{ include "grafana.namespace" . }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + labels: + {{- include "grafana.labels" . | nindent 4 }} +data: + run.sh: |- + @test "Test Health" { + url="http://{{ include "grafana.fullname" . }}/api/health" + + code=$(wget --server-response --spider --timeout 90 --tries 10 ${url} 2>&1 | awk '/^ HTTP/{print $2}') + [ "$code" == "200" ] + } +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-podsecuritypolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-podsecuritypolicy.yaml new file mode 100644 index 0000000000..1821772a45 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-podsecuritypolicy.yaml @@ -0,0 +1,32 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "grafana.fullname" . }}-test + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + labels: + {{- include "grafana.labels" . | nindent 4 }} +spec: + allowPrivilegeEscalation: true + privileged: false + hostNetwork: false + hostIPC: false + hostPID: false + fsGroup: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + runAsUser: + rule: RunAsAny + volumes: + - configMap + - downwardAPI + - emptyDir + - projected + - csi + - secret +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-role.yaml new file mode 100644 index 0000000000..cb4c782040 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-role.yaml @@ -0,0 +1,17 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "grafana.fullname" . }}-test + namespace: {{ include "grafana.namespace" . }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + labels: + {{- include "grafana.labels" . | nindent 4 }} +rules: + - apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ include "grafana.fullname" . }}-test] +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-rolebinding.yaml new file mode 100644 index 0000000000..f40d791f6c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "grafana.fullname" . }}-test + namespace: {{ include "grafana.namespace" . }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + labels: + {{- include "grafana.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "grafana.fullname" . }}-test +subjects: + - kind: ServiceAccount + name: {{ include "grafana.serviceAccountNameTest" . }} + namespace: {{ include "grafana.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-serviceaccount.yaml new file mode 100644 index 0000000000..38fba3596a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test-serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.testFramework.enabled .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + name: {{ include "grafana.serviceAccountNameTest" . }} + namespace: {{ include "grafana.namespace" . }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test.yaml new file mode 100644 index 0000000000..83aaa185c2 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/templates/tests/test.yaml @@ -0,0 +1,53 @@ +{{- if .Values.testFramework.enabled }} +{{- $root := . }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "grafana.fullname" . }}-test + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + namespace: {{ include "grafana.namespace" . }} +spec: + serviceAccountName: {{ include "grafana.serviceAccountNameTest" . }} + {{- with .Values.testFramework.securityContext }} + securityContext: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or .Values.image.pullSecrets .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "grafana.imagePullSecrets" (dict "root" $root "imagePullSecrets" .Values.image.pullSecrets) | nindent 4 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- tpl (toYaml .) $root | nindent 4 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ .Release.Name }}-test + image: "{{ template "system_default_registry" . | default .Values.testFramework.image.registry }}/{{ .Values.testFramework.image.repository }}:{{ .Values.testFramework.image.tag }}" + imagePullPolicy: "{{ .Values.testFramework.imagePullPolicy}}" + command: ["/opt/bats/bin/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + {{- with .Values.testFramework.resources }} + resources: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tests + configMap: + name: {{ include "grafana.fullname" . }}-test + restartPolicy: Never +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/values.yaml new file mode 100644 index 0000000000..c338ae041e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/grafana/values.yaml @@ -0,0 +1,1365 @@ +global: + cattle: + systemDefaultRegistry: "" + + # To help compatibility with other charts which use global.imagePullSecrets. + # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). + # Can be templated. + # global: + # imagePullSecrets: + # - name: pullSecret1 + # - name: pullSecret2 + # or + # global: + # imagePullSecrets: + # - pullSecret1 + # - pullSecret2 + imagePullSecrets: [] + +rbac: + create: true + ## Use an existing ClusterRole/Role (depending on rbac.namespaced false/true) + # useExistingRole: name-of-some-role + # useExistingClusterRole: name-of-some-clusterRole + pspEnabled: false + pspUseAppArmor: false + namespaced: false + extraRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] + extraClusterRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] +serviceAccount: + create: true + name: + nameTest: + ## ServiceAccount labels. + labels: {} + ## Service account annotations. Can be templated. + # annotations: + # eks.amazonaws.com/role-arn: arn:aws:iam::123456789000:role/iam-role-name-here + + ## autoMount is deprecated in favor of automountServiceAccountToken + # autoMount: false + automountServiceAccountToken: true + +replicas: 1 + +## Create a headless service for the deployment +headlessService: false + +## Should the service account be auto mounted on the pod +automountServiceAccountToken: true + +## Create HorizontalPodAutoscaler object for deployment type +# +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPU: "60" + targetMemory: "" + behavior: {} + +## See `kubectl explain poddisruptionbudget.spec` for more +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} +# apiVersion: "" +# minAvailable: 1 +# maxUnavailable: 1 + +## See `kubectl explain deployment.spec.strategy` for more +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +deploymentStrategy: + type: RollingUpdate + +readinessProbe: + httpGet: + path: /api/health + port: 3000 + +livenessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 60 + timeoutSeconds: 30 + failureThreshold: 10 + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: "default-scheduler" + +image: + repository: rancher/mirrored-grafana-grafana + # Overrides the Grafana image tag whose default is the chart appVersion + tag: 11.1.0 + sha: "" + pullPolicy: IfNotPresent + + ## 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/ + ## Can be templated. + ## + pullSecrets: [] + # - myRegistrKeySecretName + +testFramework: + enabled: false + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: true + runAsUser: 1000 + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +# dns configuration for pod +dnsPolicy: ~ +dnsConfig: {} + # nameservers: + # - 8.8.8.8 + # options: + # - name: ndots + # value: "2" + # - name: edns0 + +securityContext: + runAsNonRoot: true + runAsUser: 472 + runAsGroup: 472 + fsGroup: 472 + +containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + +# Enable creating the grafana configmap +createConfigmap: true + +# Extra configmaps to mount in grafana pods +# Values are templated. +extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /etc/grafana/ssl/ + # subPath: certificates.crt # (optional) + # configMap: certs-configmap + # readOnly: true + + +extraEmptyDirMounts: [] + # - name: provisioning-notifiers + # mountPath: /etc/grafana/provisioning/notifiers + + +# Apply extra labels to common labels. +extraLabels: {} + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +downloadDashboardsImage: + repository: rancher/mirrored-curlimages-curl + tag: 8.9.1 + sha: "" + pullPolicy: IfNotPresent + +downloadDashboards: + env: {} + envFromSecret: "" + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + +## Pod Annotations +# podAnnotations: {} + +## ConfigMap Annotations +# configMapAnnotations: {} + # argocd.argoproj.io/sync-options: Replace=true + +## Pod Labels +# podLabels: {} + +podPortName: grafana +gossipPortName: gossip +## Deployment annotations +# annotations: {} + +## Expose the grafana 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: + enabled: true + type: ClusterIP + # Set the ip family policy to configure dual-stack see [Configure dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) + ipFamilyPolicy: "" + # Sets the families that should be supported and the order in which they should be applied to ClusterIP as well. Can be IPv4 and/or IPv6. + ipFamilies: [] + loadBalancerIP: "" + loadBalancerClass: "" + loadBalancerSourceRanges: [] + port: 80 + targetPort: 3000 + # targetPort: 4181 To be used with a proxy extraContainer + ## Service annotations. Can be templated. + annotations: {} + labels: {} + portName: service + # Adds the appProtocol field to the service. This allows to work with istio protocol selection. Ex: "http" or "tcp" + appProtocol: "" + +serviceMonitor: + ## If true, a ServiceMonitor CR is created for a prometheus operator + ## https://github.com/coreos/prometheus-operator + ## + enabled: false + path: /metrics + # namespace: monitoring (defaults to use the namespace this chart is deployed to) + labels: {} + interval: 30s + scheme: http + tlsConfig: {} + scrapeTimeout: 30s + relabelings: [] + metricRelabelings: [] + targetLabels: [] + +extraExposePorts: [] + # - name: keycloak + # port: 8080 + # targetPort: 8080 + +# overrides pod.spec.hostAliases in the grafana deployment's pods +hostAliases: [] + # - ip: "1.2.3.4" + # hostnames: + # - "my.host.com" + +ingress: + 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: / + + # 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 + +resources: {} +# limits: +# cpu: 100m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/user-guide/node-selection/ +# +nodeSelector: {} + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] + +## Affinity for pod assignment (evaluated as template) +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## +affinity: {} + +## Topology Spread Constraints +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## +topologySpreadConstraints: [] + +## Additional init containers (evaluated as template) +## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ +## +extraInitContainers: [] + +## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod +extraContainers: "" +# extraContainers: | +# - name: proxy +# image: quay.io/gambol99/keycloak-proxy:latest +# args: +# - -provider=github +# - -client-id= +# - -client-secret= +# - -github-org= +# - -email-domain=* +# - -cookie-secret= +# - -http-address=http://0.0.0.0:4181 +# - -upstream-url=http://127.0.0.1:3000 +# ports: +# - name: proxy-web +# containerPort: 4181 + +## Volumes that can be used in init containers that will not be mounted to deployment pods +extraContainerVolumes: [] +# - name: volume-from-secret +# secret: +# secretName: secret-to-mount +# - name: empty-dir-volume +# emptyDir: {} + +## Enable persistence using Persistent Volume Claims +## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + type: pvc + enabled: false + # storageClassName: default + accessModes: + - ReadWriteOnce + size: 10Gi + # annotations: {} + finalizers: + - kubernetes.io/pvc-protection + # selectorLabels: {} + ## Sub-directory of the PV to mount. Can be templated. + # subPath: "" + ## Name of an existing PVC. Can be templated. + # existingClaim: + ## Extra labels to apply to a PVC. + extraPvcLabels: {} + disableWarning: false + + ## If persistence is not enabled, this allows to mount the + ## local storage in-memory to improve performance + ## + inMemory: + enabled: false + ## The maximum usage on memory medium EmptyDir would be + ## the minimum value between the SizeLimit specified + ## here and the sum of memory limits of all containers in a pod + ## + # sizeLimit: 300Mi + + ## If 'lookupVolumeName' is set to true, Helm will attempt to retrieve + ## the current value of 'spec.volumeName' and incorporate it into the template. + lookupVolumeName: true + +initChownData: + ## If false, data ownership will not be reset at startup + ## This allows the grafana-server to be run with an arbitrary user + ## + enabled: true + + ## initChownData container image + ## + image: + repository: rancher/mirrored-library-busybox + tag: "1.31.1" + sha: "" + pullPolicy: IfNotPresent + + ## initChownData resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + securityContext: + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + capabilities: + add: + - CHOWN + +# Administrator credentials when not using an existing secret (see below) +adminUser: admin +# adminPassword: strongpassword + +# Use an existing secret for the admin user. +admin: + ## Name of the secret. Can be templated. + existingSecret: "" + userKey: admin-user + passwordKey: admin-password + +## Define command to be executed at startup by grafana container +## Needed if using `vault-env` to manage secrets (ref: https://banzaicloud.com/blog/inject-secrets-into-pods-vault/) +## Default is "run.sh" as defined in grafana's Dockerfile +# command: +# - "sh" +# - "/run.sh" + +## Optionally define args if command is used +## Needed if using `hashicorp/envconsul` to manage secrets +## By default no arguments are set +# args: +# - "-secret" +# - "secret/grafana" +# - "./grafana" + +## Extra environment variables that will be pass onto deployment pods +## +## to provide grafana with access to CloudWatch on AWS EKS: +## 1. create an iam role of type "Web identity" with provider oidc.eks.* (note the provider for later) +## 2. edit the "Trust relationships" of the role, add a line inside the StringEquals clause using the +## same oidc eks provider as noted before (same as the existing line) +## also, replace NAMESPACE and prometheus-operator-grafana with the service account namespace and name +## +## "oidc.eks.us-east-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:sub": "system:serviceaccount:NAMESPACE:prometheus-operator-grafana", +## +## 3. attach a policy to the role, you can use a built in policy called CloudWatchReadOnlyAccess +## 4. use the following env: (replace 123456789000 and iam-role-name-here with your aws account number and role name) +## +## env: +## AWS_ROLE_ARN: arn:aws:iam::123456789000:role/iam-role-name-here +## AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token +## AWS_REGION: us-east-1 +## +## 5. uncomment the EKS section in extraSecretMounts: below +## 6. uncomment the annotation section in the serviceAccount: above +## make sure to replace arn:aws:iam::123456789000:role/iam-role-name-here with your role arn + +env: {} + +## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. +## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core +## Renders in container spec as: +## env: +## ... +## - name: +## valueFrom: +## +envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + +## The name of a secret in the same kubernetes namespace which contain values to be added to the environment +## This can be useful for auth tokens, etc. Value is templated. +envFromSecret: "" + +## Sensible environment variables that will be rendered as new secret object +## This can be useful for auth tokens, etc. +## If the secret values contains "{{", they'll need to be properly escaped so that they are not interpreted by Helm +## ref: https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function +envRenderSecret: {} + +## The names of secrets in the same kubernetes namespace which contain values to be added to the environment +## Each entry should contain a name key, and can optionally specify whether the secret must be defined with an optional key. +## Name is templated. +envFromSecrets: [] +## - name: secret-name +## prefix: prefix +## optional: true + +## The names of conifgmaps in the same kubernetes namespace which contain values to be added to the environment +## Each entry should contain a name key, and can optionally specify whether the configmap must be defined with an optional key. +## Name is templated. +## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#configmapenvsource-v1-core +envFromConfigMaps: [] +## - name: configmap-name +## prefix: prefix +## optional: true + +# Inject Kubernetes services as environment variables. +# See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#environment-variables +enableServiceLinks: true + +## Additional grafana server secret mounts +# Defines additional mounts with secrets. Secrets must be manually created in the namespace. +extraSecretMounts: [] + # - name: secret-files + # mountPath: /etc/secrets + # secretName: grafana-secret-files + # readOnly: true + # subPath: "" + # + # for AWS EKS (cloudwatch) use the following (see also instruction in env: above) + # - name: aws-iam-token + # mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount + # readOnly: true + # projected: + # defaultMode: 420 + # sources: + # - serviceAccountToken: + # audience: sts.amazonaws.com + # expirationSeconds: 86400 + # path: token + # + # for CSI e.g. Azure Key Vault use the following + # - name: secrets-store-inline + # mountPath: /run/secrets + # readOnly: true + # csi: + # driver: secrets-store.csi.k8s.io + # readOnly: true + # volumeAttributes: + # secretProviderClass: "akv-grafana-spc" + # nodePublishSecretRef: # Only required when using service principal mode + # name: grafana-akv-creds # Only required when using service principal mode + +## Additional grafana server volume mounts +# Defines additional volume mounts. +extraVolumeMounts: [] + # - name: extra-volume-0 + # mountPath: /mnt/volume0 + # readOnly: true + # - name: extra-volume-1 + # mountPath: /mnt/volume1 + # readOnly: true + # - name: grafana-secrets + # mountPath: /mnt/volume2 + +## Additional Grafana server volumes +extraVolumes: [] + # - name: extra-volume-0 + # existingClaim: volume-claim + # - name: extra-volume-1 + # hostPath: + # path: /usr/shared/ + # type: "" + # - name: grafana-secrets + # csi: + # driver: secrets-store.csi.k8s.io + # readOnly: true + # volumeAttributes: + # secretProviderClass: "grafana-env-spc" + +## Container Lifecycle Hooks. Execute a specific bash command or make an HTTP request +lifecycleHooks: {} + # postStart: + # exec: + # command: [] + +## Pass the plugins you want installed as a list. +## +plugins: [] + # - digrich-bubblechart-panel + # - grafana-clock-panel + ## You can also use other plugin download URL, as long as they are valid zip files, + ## and specify the name of the plugin after the semicolon. Like this: + # - https://grafana.com/api/plugins/marcusolsson-json-datasource/versions/1.3.2/download;marcusolsson-json-datasource + +## Configure grafana datasources +## ref: http://docs.grafana.org/administration/provisioning/#datasources +## +datasources: {} +# datasources.yaml: +# apiVersion: 1 +# datasources: +# - name: Prometheus +# type: prometheus +# url: http://prometheus-prometheus-server +# access: proxy +# isDefault: true +# - name: CloudWatch +# type: cloudwatch +# access: proxy +# uid: cloudwatch +# editable: false +# jsonData: +# authType: default +# defaultRegion: us-east-1 +# deleteDatasources: [] +# - name: Prometheus + +## Configure grafana alerting (can be templated) +## ref: http://docs.grafana.org/administration/provisioning/#alerting +## +alerting: {} + # rules.yaml: + # apiVersion: 1 + # groups: + # - orgId: 1 + # name: '{{ .Chart.Name }}_my_rule_group' + # folder: my_first_folder + # interval: 60s + # rules: + # - uid: my_id_1 + # title: my_first_rule + # condition: A + # data: + # - refId: A + # datasourceUid: '-100' + # model: + # conditions: + # - evaluator: + # params: + # - 3 + # type: gt + # operator: + # type: and + # query: + # params: + # - A + # reducer: + # type: last + # type: query + # datasource: + # type: __expr__ + # uid: '-100' + # expression: 1==0 + # intervalMs: 1000 + # maxDataPoints: 43200 + # refId: A + # type: math + # dashboardUid: my_dashboard + # panelId: 123 + # noDataState: Alerting + # for: 60s + # annotations: + # some_key: some_value + # labels: + # team: sre_team_1 + # contactpoints.yaml: + # secret: + # apiVersion: 1 + # contactPoints: + # - orgId: 1 + # name: cp_1 + # receivers: + # - uid: first_uid + # type: pagerduty + # settings: + # integrationKey: XXX + # severity: critical + # class: ping failure + # component: Grafana + # group: app-stack + # summary: | + # {{ `{{ include "default.message" . }}` }} + +## Configure notifiers +## ref: http://docs.grafana.org/administration/provisioning/#alert-notification-channels +## +notifiers: {} +# notifiers.yaml: +# notifiers: +# - name: email-notifier +# type: email +# uid: email1 +# # either: +# org_id: 1 +# # or +# org_name: Main Org. +# is_default: true +# settings: +# addresses: an_email_address@example.com +# delete_notifiers: + +## Configure grafana dashboard providers +## ref: http://docs.grafana.org/administration/provisioning/#dashboards +## +## `path` must be /var/lib/grafana/dashboards/ +## +dashboardProviders: {} +# dashboardproviders.yaml: +# apiVersion: 1 +# providers: +# - name: 'default' +# orgId: 1 +# folder: '' +# type: file +# disableDeletion: false +# editable: true +# options: +# path: /var/lib/grafana/dashboards/default + +## Configure grafana dashboard to import +## NOTE: To use dashboards you must also enable/configure dashboardProviders +## ref: https://grafana.com/dashboards +## +## dashboards per provider, use provider name as key. +## +dashboards: {} + # default: + # some-dashboard: + # json: | + # $RAW_JSON + # custom-dashboard: + # file: dashboards/custom-dashboard.json + # prometheus-stats: + # gnetId: 2 + # revision: 2 + # datasource: Prometheus + # local-dashboard: + # url: https://example.com/repository/test.json + # token: '' + # local-dashboard-base64: + # url: https://example.com/repository/test-b64.json + # token: '' + # b64content: true + # local-dashboard-gitlab: + # url: https://example.com/repository/test-gitlab.json + # gitlabToken: '' + # local-dashboard-bitbucket: + # url: https://example.com/repository/test-bitbucket.json + # bearerToken: '' + # local-dashboard-azure: + # url: https://example.com/repository/test-azure.json + # basic: '' + # acceptHeader: '*/*' + +## Reference to external ConfigMap per provider. Use provider name as key and ConfigMap name as value. +## A provider dashboards must be defined either by external ConfigMaps or in values.yaml, not in both. +## ConfigMap data example: +## +## data: +## example-dashboard.json: | +## RAW_JSON +## +dashboardsConfigMaps: {} +# default: "" + +## Grafana's primary configuration +## NOTE: values in map will be converted to ini format +## ref: http://docs.grafana.org/installation/configuration/ +## +grafana.ini: + paths: + data: /var/lib/grafana/ + logs: /var/log/grafana + plugins: /var/lib/grafana/plugins + provisioning: /etc/grafana/provisioning + analytics: + check_for_updates: true + log: + mode: console + grafana_net: + url: https://grafana.net + server: + domain: "{{ if (and .Values.ingress.enabled .Values.ingress.hosts) }}{{ .Values.ingress.hosts | first }}{{ else }}''{{ end }}" +## grafana Authentication can be enabled with the following values on grafana.ini + # server: + # The full public facing url you use in browser, used for redirects and emails + # root_url: + # https://grafana.com/docs/grafana/latest/auth/github/#enable-github-in-grafana + # auth.github: + # enabled: false + # allow_sign_up: false + # scopes: user:email,read:org + # auth_url: https://github.com/login/oauth/authorize + # token_url: https://github.com/login/oauth/access_token + # api_url: https://api.github.com/user + # team_ids: + # allowed_organizations: + # client_id: + # client_secret: +## LDAP Authentication can be enabled with the following values on grafana.ini +## NOTE: Grafana will fail to start if the value for ldap.toml is invalid + # auth.ldap: + # enabled: true + # allow_sign_up: true + # config_file: /etc/grafana/ldap.toml + +## Grafana's LDAP configuration +## Templated by the template in _helpers.tpl +## NOTE: To enable the grafana.ini must be configured with auth.ldap.enabled +## ref: http://docs.grafana.org/installation/configuration/#auth-ldap +## ref: http://docs.grafana.org/installation/ldap/#configuration +ldap: + enabled: false + # `existingSecret` is a reference to an existing secret containing the ldap configuration + # for Grafana in a key `ldap-toml`. + existingSecret: "" + # `config` is the content of `ldap.toml` that will be stored in the created secret + config: "" + # config: |- + # verbose_logging = true + + # [[servers]] + # host = "my-ldap-server" + # port = 636 + # use_ssl = true + # start_tls = false + # ssl_skip_verify = false + # bind_dn = "uid=%s,ou=users,dc=myorg,dc=com" + +## Grafana's SMTP configuration +## NOTE: To enable, grafana.ini must be configured with smtp.enabled +## ref: http://docs.grafana.org/installation/configuration/#smtp +smtp: + # `existingSecret` is a reference to an existing secret containing the smtp configuration + # for Grafana. + existingSecret: "" + userKey: "user" + passwordKey: "password" + +## Sidecars that collect the configmaps with specified label and stores the included files them into the respective folders +## Requires at least Grafana 5 to work and can't be used together with parameters dashboardProviders, datasources and dashboards +sidecar: + image: + repository: rancher/mirrored-kiwigrid-k8s-sidecar + tag: 1.27.4 + sha: "" + imagePullPolicy: IfNotPresent + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + # skipTlsVerify Set to true to skip tls verification for kube api calls + # skipTlsVerify: true + enableUniqueFilenames: false + readinessProbe: {} + livenessProbe: {} + # Log level default for all sidecars. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. Defaults to INFO + # logLevel: INFO + alerts: + enabled: false + # Additional environment variables for the alerts sidecar + env: {} + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + # label that the configmaps with alert are marked with + label: grafana_alert + # value of label that the configmaps with alert are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # If specified, the sidecar will search for alert config-maps inside this namespace. + # 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # 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: 3600 + # + # 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 (sic!) + # watchClientTimeout: 60 + # + # Endpoint to send request to reload alerts + reloadURL: "http://localhost:3000/api/admin/provisioning/alerting/reload" + # Absolute path to shell script to execute after a alert got reloaded + script: null + skipReload: false + # This is needed if skipReload is true, to load any alerts defined at startup time. + # Deploy the alert sidecar as an initContainer. + initAlerts: false + # Additional alert sidecar volume mounts + extraMounts: [] + # Sets the size limit of the alert sidecar emptyDir volume + sizeLimit: {} + dashboards: + enabled: false + # Additional environment variables for the dashboards sidecar + env: {} + ## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. + ## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core + ## Renders in container spec as: + ## env: + ## ... + ## - name: + ## valueFrom: + ## + envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + SCProvider: true + # label that the configmaps with dashboards are marked with + label: grafana_dashboard + # value of label that the configmaps with dashboards are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # folder in the pod that should hold the collected dashboards (unless `defaultFolderName` is set) + folder: /tmp/dashboards + # The default folder name, it will create a subfolder under the `folder` and put dashboards in there instead + defaultFolderName: null + # Namespaces list. 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # If specified, the sidecar will look for annotation with this name to create folder and put graph here. + # You can use this parameter together with `provider.foldersFromFilesStructure`to annotate configmaps and create folder structure. + folderAnnotation: null + # Endpoint to send request to reload alerts + reloadURL: "http://localhost:3000/api/admin/provisioning/dashboards/reload" + # Absolute path to shell script to execute after a configmap got reloaded + script: null + skipReload: false + # 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: 3600 + # + # 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 (sic!) + # watchClientTimeout: 60 + # + # provider configuration that lets grafana manage the dashboards + provider: + # name of the provider, should be unique + name: sidecarProvider + # orgid as configured in grafana + orgid: 1 + # folder in which the dashboards should be imported in grafana + folder: '' + # folder UID. will be automatically generated if not specified + folderUid: '' + # type of the provider + type: file + # disableDelete to activate a import-only behaviour + disableDelete: false + # allow updating provisioned dashboards from the UI + allowUiUpdates: false + # allow Grafana to replicate dashboard structure from filesystem + foldersFromFilesStructure: false + # Additional dashboard sidecar volume mounts + extraMounts: [] + # Sets the size limit of the dashboard sidecar emptyDir volume + sizeLimit: {} + datasources: + enabled: false + # Additional environment variables for the datasourcessidecar + env: {} + ## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. + ## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core + ## Renders in container spec as: + ## env: + ## ... + ## - name: + ## valueFrom: + ## + envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + # label that the configmaps with datasources are marked with + label: grafana_datasource + # value of label that the configmaps with datasources are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # If specified, the sidecar will search for datasource config-maps inside this namespace. + # 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # 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: 3600 + # + # 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 (sic!) + # watchClientTimeout: 60 + # + # Endpoint to send request to reload datasources + reloadURL: "http://localhost:3000/api/admin/provisioning/datasources/reload" + # Absolute path to shell script to execute after a datasource got reloaded + script: null + skipReload: true + # This is needed if skipReload is true, to load any datasources defined at startup time. + # Deploy the datasources sidecar as an initContainer. + initDatasources: true + # Sets the size limit of the datasource sidecar emptyDir volume + sizeLimit: {} + plugins: + enabled: false + # Additional environment variables for the plugins sidecar + env: {} + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + # label that the configmaps with plugins are marked with + label: grafana_plugin + # value of label that the configmaps with plugins are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # If specified, the sidecar will search for plugin config-maps inside this namespace. + # 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # 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: 3600 + # + # 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 (sic!) + # watchClientTimeout: 60 + # + # Endpoint to send request to reload plugins + reloadURL: "http://localhost:3000/api/admin/provisioning/plugins/reload" + # Absolute path to shell script to execute after a plugin got reloaded + script: null + skipReload: false + # Deploy the datasource sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any plugins defined at startup time. + initPlugins: false + # Sets the size limit of the plugin sidecar emptyDir volume + sizeLimit: {} + notifiers: + enabled: false + # Additional environment variables for the notifierssidecar + env: {} + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + # label that the configmaps with notifiers are marked with + label: grafana_notifier + # value of label that the configmaps with notifiers are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # If specified, the sidecar will search for notifier config-maps inside this namespace. + # 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 requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # 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: 3600 + # + # 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 (sic!) + # watchClientTimeout: 60 + # + # Endpoint to send request to reload notifiers + reloadURL: "http://localhost:3000/api/admin/provisioning/notifications/reload" + # Absolute path to shell script to execute after a notifier got reloaded + script: null + skipReload: false + # Deploy the notifier sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any notifiers defined at startup time. + initNotifiers: false + # Sets the size limit of the notifier sidecar emptyDir volume + sizeLimit: {} + +## Override the deployment namespace +## +namespaceOverride: "" + +## Number of old ReplicaSets to retain +## +revisionHistoryLimit: 10 + +## Add a seperate remote image renderer deployment/service +imageRenderer: + deploymentStrategy: {} + # Enable the image-renderer deployment & service + enabled: false + replicas: 1 + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPU: "60" + targetMemory: "" + behavior: {} + image: + # image-renderer Image repository + repository: rancher/mirrored-grafana-grafana-image-renderer + # image-renderer Image tag + tag: 3.11.1 + # image-renderer Image sha (optional) + sha: "" + # image-renderer ImagePullPolicy + pullPolicy: Always + # extra environment variables + env: + HTTP_HOST: "0.0.0.0" + # RENDERING_ARGS: --no-sandbox,--disable-gpu,--window-size=1280x758 + # RENDERING_MODE: clustered + # IGNORE_HTTPS_ERRORS: true + + ## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. + ## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core + ## Renders in container spec as: + ## env: + ## ... + ## - name: + ## valueFrom: + ## + envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + + # image-renderer deployment serviceAccount + serviceAccountName: "" + # image-renderer deployment securityContext + securityContext: {} + # image-renderer deployment container securityContext + containerSecurityContext: + seccompProfile: + type: RuntimeDefault + capabilities: + drop: ['ALL'] + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + ## image-renderer pod annotation + podAnnotations: {} + # image-renderer deployment Host Aliases + hostAliases: [] + # image-renderer deployment priority class + priorityClassName: '' + service: + # Enable the image-renderer service + enabled: true + # image-renderer service port name + portName: 'http' + # image-renderer service port used by both service and deployment + port: 8081 + targetPort: 8081 + # Adds the appProtocol field to the image-renderer service. This allows to work with istio protocol selection. Ex: "http" or "tcp" + appProtocol: "" + serviceMonitor: + ## If true, a ServiceMonitor CRD is created for a prometheus operator + ## https://github.com/coreos/prometheus-operator + ## + enabled: false + path: /metrics + # namespace: monitoring (defaults to use the namespace this chart is deployed to) + labels: {} + interval: 1m + scheme: http + tlsConfig: {} + scrapeTimeout: 30s + relabelings: [] + # See: https://doc.crds.dev/github.com/prometheus-operator/kube-prometheus/monitoring.coreos.com/ServiceMonitor/v1@v0.11.0#spec-targetLabels + targetLabels: [] + # - targetLabel1 + # - targetLabel2 + # If https is enabled in Grafana, this needs to be set as 'https' to correctly configure the callback used in Grafana + grafanaProtocol: http + # In case a sub_path is used this needs to be added to the image renderer callback + grafanaSubPath: "" + # name of the image-renderer port on the pod + podPortName: http + # number of image-renderer replica sets to keep + revisionHistoryLimit: 10 + networkPolicy: + # Enable a NetworkPolicy to limit inbound traffic to only the created grafana pods + limitIngress: true + # Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods + limitEgress: false + # Allow additional services to access image-renderer (eg. Prometheus operator when ServiceMonitor is enabled) + extraIngressSelectors: [] + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + ## Node labels for pod assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + # + nodeSelector: {} + + ## Tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + + ## Affinity for pod assignment (evaluated as template) + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## + affinity: {} + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: "default-scheduler" + + # Extra configmaps to mount in image-renderer pods + extraConfigmapMounts: [] + + # Extra secrets to mount in image-renderer pods + extraSecretMounts: [] + + # Extra volumes to mount in image-renderer pods + extraVolumeMounts: [] + + # Extra volumes for image-renderer pods + extraVolumes: [] + +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. + ## + enabled: false + ## @param networkPolicy.allowExternal Don't require client label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to grafana port defined. + ## When true, grafana will accept connections from any source + ## (with the correct destination port). + ## + ingress: true + ## @param networkPolicy.ingress When true enables the creation + ## an ingress network policy + ## + allowExternal: true + ## @param networkPolicy.explicitNamespacesSelector A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed + ## If explicitNamespacesSelector is missing or set to {}, only client Pods that are in the networkPolicy's namespace + ## and that match other criteria, the ones that have the good label, can reach the grafana. + ## But sometimes, we want the grafana to be accessible to clients from other namespaces, in this case, we can use this + ## LabelSelector to select these namespaces, note that the networkPolicy's namespace should also be explicitly added. + ## + ## Example: + ## explicitNamespacesSelector: + ## matchLabels: + ## role: frontend + ## matchExpressions: + ## - {key: role, operator: In, values: [frontend]} + ## + explicitNamespacesSelector: {} + ## + ## + ## + ## + ## + ## + egress: + ## @param networkPolicy.egress.enabled When enabled, an egress network policy will be + ## created allowing grafana to connect to external data sources from kubernetes cluster. + enabled: false + ## + ## @param networkPolicy.egress.blockDNSResolution When enabled, DNS resolution will be blocked + ## for all pods in the grafana namespace. + blockDNSResolution: false + ## + ## @param networkPolicy.egress.ports Add individual ports to be allowed by the egress + ports: [] + ## Add ports to the egress by specifying - port: + ## E.X. + ## - port: 80 + ## - port: 443 + ## + ## @param networkPolicy.egress.to Allow egress traffic to specific destinations + to: [] + ## Add destinations to the egress by specifying - ipBlock: + ## E.X. + ## to: + ## - namespaceSelector: + ## matchExpressions: + ## - {key: role, operator: In, values: [grafana]} + ## + ## + ## + ## + ## + +# Enable backward compatibility of kubernetes where version below 1.13 doesn't have the enableServiceLinks option +enableKubeBackwardCompatibility: false +useStatefulSet: false +# Create a dynamic manifests via values: +extraObjects: [] + # - apiVersion: "kubernetes-client.io/v1" + # kind: ExternalSecret + # metadata: + # name: grafana-secrets + # spec: + # backendType: gcpSecretsManager + # data: + # - key: grafana-admin-password + # name: adminPassword + +# assertNoLeakedSecrets is a helper function defined in _helpers.tpl that checks if secret +# values are not exposed in the rendered grafana.ini configmap. It is enabled by default. +# +# To pass values into grafana.ini without exposing them in a configmap, use variable expansion: +# https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#variable-expansion +# +# Alternatively, if you wish to allow secret values to be exposed in the rendered grafana.ini configmap, +# you can disable this check by setting assertNoLeakedSecrets to false. +assertNoLeakedSecrets: true diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/Chart.yaml new file mode 100644 index 0000000000..980dcf9cfb --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: hardenedKubelet +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedKubelet/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/Chart.yaml new file mode 100644 index 0000000000..759ed7c38d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: hardenedNodeExporter +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/hardenedNodeExporter/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/Chart.yaml new file mode 100644 index 0000000000..39ed968500 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: k3sServer +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/k3sServer/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/Chart.yaml new file mode 100644 index 0000000000..1360e832be --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/Chart.yaml @@ -0,0 +1,32 @@ +annotations: + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/prometheus-community/helm-charts + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-kube-state-metrics +apiVersion: v2 +appVersion: 2.12.0 +description: Install kube-state-metrics to generate and expose cluster-level metrics +home: https://github.com/kubernetes/kube-state-metrics/ +keywords: +- metric +- monitoring +- prometheus +- kubernetes +maintainers: +- email: tariq.ibrahim@mulesoft.com + name: tariq1890 +- email: manuel@rueg.eu + name: mrueg +- email: david@0xdc.me + name: dotdc +name: kube-state-metrics +sources: +- https://github.com/kubernetes/kube-state-metrics/ +type: application +version: 5.21.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/README.md new file mode 100644 index 0000000000..843be89e69 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/README.md @@ -0,0 +1,85 @@ +# kube-state-metrics Helm Chart + +Installs the [kube-state-metrics agent](https://github.com/kubernetes/kube-state-metrics). + +## Get Repository Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall 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._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Migrating from stable/kube-state-metrics and kubernetes/kube-state-metrics + +You can upgrade in-place: + +1. [get repository info](#get-repository-info) +1. [upgrade](#upgrading-chart) your existing release name using the new chart repository + +## Upgrading to v3.0.0 + +v3.0.0 includes kube-state-metrics v2.0, see the [changelog](https://github.com/kubernetes/kube-state-metrics/blob/release-2.0/CHANGELOG.md) for major changes on the application-side. + +The upgraded chart now the following changes: + +* Dropped support for helm v2 (helm v3 or later is required) +* collectors key was renamed to resources +* namespace key was renamed to namespaces + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: + +```console +helm show values prometheus-community/kube-state-metrics +``` + +### kube-rbac-proxy + +You can enable `kube-state-metrics` endpoint protection using `kube-rbac-proxy`. By setting `kubeRBACProxy.enabled: true`, this chart will deploy one RBAC proxy container per endpoint (metrics & telemetry). +To authorize access, authenticate your requests (via a `ServiceAccount` for example) with a `ClusterRole` attached such as: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kube-state-metrics-read +rules: + - apiGroups: [ "" ] + resources: ["services/kube-state-metrics"] + verbs: + - get +``` + +See [kube-rbac-proxy examples](https://github.com/brancz/kube-rbac-proxy/tree/master/examples/resource-attributes) for more details. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/NOTES.txt new file mode 100644 index 0000000000..3589c24ec3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/NOTES.txt @@ -0,0 +1,23 @@ +kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects. +The exposed metrics can be found here: +https://github.com/kubernetes/kube-state-metrics/blob/master/docs/README.md#exposed-metrics + +The metrics are exported on the HTTP endpoint /metrics on the listening port. +In your case, {{ template "kube-state-metrics.fullname" . }}.{{ template "kube-state-metrics.namespace" . }}.svc.cluster.local:{{ .Values.service.port }}/metrics + +They are served either as plaintext or protobuf depending on the Accept header. +They are designed to be consumed either by Prometheus itself or by a scraper that is compatible with scraping a Prometheus client endpoint. + +{{- if .Values.kubeRBACProxy.enabled}} + +kube-rbac-proxy endpoint protections is enabled: +- Metrics endpoints are now HTTPS +- Ensure that the client authenticates the requests (e.g. via service account) with the following role permissions: +``` +rules: + - apiGroups: [ "" ] + resources: ["services/{{ template "kube-state-metrics.fullname" . }}"] + verbs: + - get +``` +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/_helpers.tpl new file mode 100644 index 0000000000..ed277fbb53 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/_helpers.tpl @@ -0,0 +1,196 @@ +# Rancher +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +{{- define "monitoring_registry" -}} + {{- $temp_registry := (include "system_default_registry" .) -}} + {{- if $temp_registry -}} + {{- trimSuffix "/" $temp_registry -}} + {{- else -}} + {{- .Values.global.imageRegistry -}} + {{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kube-state-metrics.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 "kube-state-metrics.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 "kube-state-metrics.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "kube-state-metrics.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "kube-state-metrics.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kube-state-metrics.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Generate basic labels +*/}} +{{- define "kube-state-metrics.labels" }} +helm.sh/chart: {{ template "kube-state-metrics.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: metrics +app.kubernetes.io/part-of: {{ template "kube-state-metrics.name" . }} +{{- include "kube-state-metrics.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- if .Values.releaseLabel }} +release: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kube-state-metrics.selectorLabels" }} +{{- if .Values.selectorOverride }} +{{ toYaml .Values.selectorOverride }} +{{- else }} +app.kubernetes.io/name: {{ include "kube-state-metrics.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for servicemonitor */}} +{{- define "servicemonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end -}} + +{{/* +Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) +*/}} +{{- define "kube-state-metrics.imagePullSecrets" -}} +{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} + {{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml . | trim }} + {{- else }} +- name: {{ . }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +The image to use for kube-state-metrics +*/}} +{{- define "kube-state-metrics.image" -}} +{{- $registry := (include "monitoring_registry" .) }} +{{- if .Values.image.sha }} +{{- if $registry }} +{{- printf "%s/%s:%s@%s" $registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.sha }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.sha }} +{{- end }} +{{- else }} +{{- if $registry }} +{{- printf "%s/%s:%s" $registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +The image to use for kubeRBACProxy +*/}} +{{- define "kubeRBACProxy.image" -}} +{{- $registry := (include "monitoring_registry" .) }} +{{- if .Values.kubeRBACProxy.image.sha }} +{{- if $registry }} +{{- printf "%s/%s:%s@%s" $registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) .Values.kubeRBACProxy.image.sha }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.kubeRBACProxy.image.registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) .Values.kubeRBACProxy.image.sha }} +{{- end }} +{{- else }} +{{- if $registry }} +{{- printf "%s/%s:%s" $registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.kubeRBACProxy.image.registry .Values.kubeRBACProxy.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.kubeRBACProxy.image.tag) }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000000..025cd47a88 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/ciliumnetworkpolicy.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.networkPolicy.enabled (eq .Values.networkPolicy.flavor "cilium") }} +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +spec: + endpointSelector: + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + egress: + {{- if and .Values.networkPolicy.cilium .Values.networkPolicy.cilium.kubeApiServerSelector }} + {{ toYaml .Values.networkPolicy.cilium.kubeApiServerSelector | nindent 6 }} + {{- else }} + - toEntities: + - kube-apiserver + {{- end }} + ingress: + - toPorts: + - ports: + - port: {{ .Values.service.port | quote }} + protocol: TCP + {{- if .Values.selfMonitor.enabled }} + - port: {{ .Values.selfMonitor.telemetryPort | default 8081 | quote }} + protocol: TCP + {{ end }} +{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..cf9f628d04 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create .Values.rbac.useClusterRole -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} +{{- else }} + name: {{ template "kube-state-metrics.fullname" . }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/crs-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/crs-configmap.yaml new file mode 100644 index 0000000000..d38a75a51d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/crs-configmap.yaml @@ -0,0 +1,16 @@ +{{- if .Values.customResourceState.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-customresourcestate-config + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} +data: + config.yaml: | + {{- toYaml .Values.customResourceState.config | nindent 4 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/deployment.yaml new file mode 100644 index 0000000000..2c63048cc6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/deployment.yaml @@ -0,0 +1,313 @@ +apiVersion: apps/v1 +{{- if .Values.autosharding.enabled }} +kind: StatefulSet +{{- else }} +kind: Deployment +{{- end }} +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: +{{ toYaml .Values.annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + replicas: {{ .Values.replicas }} + {{- if not .Values.autosharding.enabled }} + strategy: + type: {{ .Values.updateStrategy | default "RollingUpdate" }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- if .Values.autosharding.enabled }} + serviceName: {{ template "kube-state-metrics.fullname" . }} + volumeClaimTemplates: [] + {{- end }} + template: + metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 8 }} + {{- if .Values.podAnnotations }} + annotations: +{{ toYaml .Values.podAnnotations | indent 8 }} + {{- end }} + spec: + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + hostNetwork: {{ .Values.hostNetwork }} + serviceAccountName: {{ template "kube-state-metrics.serviceAccountName" . }} + {{- if .Values.securityContext.enabled }} + securityContext: {{- omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- with .Values.initContainers }} + initContainers: + {{- toYaml . | nindent 6 }} + {{- end }} + containers: + {{- $servicePort := ternary 9090 (.Values.service.port | default 8080) .Values.kubeRBACProxy.enabled}} + {{- $telemetryPort := ternary 9091 (.Values.selfMonitor.telemetryPort | default 8081) .Values.kubeRBACProxy.enabled}} + - name: {{ template "kube-state-metrics.name" . }} + {{- if .Values.autosharding.enabled }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- end }} + args: + {{- if .Values.extraArgs }} + {{- .Values.extraArgs | toYaml | nindent 8 }} + {{- end }} + - --port={{ $servicePort }} + {{- if .Values.collectors }} + - --resources={{ .Values.collectors | join "," }} + {{- end }} + {{- if .Values.metricLabelsAllowlist }} + - --metric-labels-allowlist={{ .Values.metricLabelsAllowlist | join "," }} + {{- end }} + {{- if .Values.metricAnnotationsAllowList }} + - --metric-annotations-allowlist={{ .Values.metricAnnotationsAllowList | join "," }} + {{- end }} + {{- if .Values.metricAllowlist }} + - --metric-allowlist={{ .Values.metricAllowlist | join "," }} + {{- end }} + {{- if .Values.metricDenylist }} + - --metric-denylist={{ .Values.metricDenylist | join "," }} + {{- end }} + {{- $namespaces := list }} + {{- if .Values.namespaces }} + {{- range $ns := join "," .Values.namespaces | split "," }} + {{- $namespaces = append $namespaces (tpl $ns $) }} + {{- end }} + {{- end }} + {{- if .Values.releaseNamespace }} + {{- $namespaces = append $namespaces ( include "kube-state-metrics.namespace" . ) }} + {{- end }} + {{- if $namespaces }} + - --namespaces={{ $namespaces | mustUniq | join "," }} + {{- end }} + {{- if .Values.namespacesDenylist }} + - --namespaces-denylist={{ tpl (.Values.namespacesDenylist | join ",") $ }} + {{- end }} + {{- if .Values.autosharding.enabled }} + - --pod=$(POD_NAME) + - --pod-namespace=$(POD_NAMESPACE) + {{- end }} + {{- if .Values.kubeconfig.enabled }} + - --kubeconfig=/opt/k8s/.kube/config + {{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - --telemetry-host=127.0.0.1 + - --telemetry-port={{ $telemetryPort }} + {{- else }} + {{- if .Values.selfMonitor.telemetryHost }} + - --telemetry-host={{ .Values.selfMonitor.telemetryHost }} + {{- end }} + {{- if .Values.selfMonitor.telemetryPort }} + - --telemetry-port={{ $telemetryPort }} + {{- end }} + {{- end }} + {{- if .Values.customResourceState.enabled }} + - --custom-resource-state-config-file=/etc/customresourcestate/config.yaml + {{- end }} + {{- if or (.Values.kubeconfig.enabled) (.Values.customResourceState.enabled) (.Values.volumeMounts) }} + volumeMounts: + {{- if .Values.kubeconfig.enabled }} + - name: kubeconfig + mountPath: /opt/k8s/.kube/ + readOnly: true + {{- end }} + {{- if .Values.customResourceState.enabled }} + - name: customresourcestate-config + mountPath: /etc/customresourcestate + readOnly: true + {{- end }} + {{- if .Values.volumeMounts }} +{{ toYaml .Values.volumeMounts | indent 8 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + image: {{ include "kube-state-metrics.image" . }} + {{- if eq .Values.kubeRBACProxy.enabled false }} + ports: + - containerPort: {{ .Values.service.port | default 8080}} + name: "http" + {{- if .Values.selfMonitor.enabled }} + - containerPort: {{ $telemetryPort }} + name: "metrics" + {{- end }} + {{- end }} + livenessProbe: + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + httpGet: + {{- if .Values.hostNetwork }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: /healthz + port: {{ $servicePort }} + scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + readinessProbe: + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + {{- if .Values.hostNetwork }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: / + port: {{ $servicePort }} + scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + resources: +{{ toYaml .Values.resources | indent 10 }} +{{- if .Values.containerSecurityContext }} + securityContext: +{{ toYaml .Values.containerSecurityContext | indent 10 }} +{{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - name: kube-rbac-proxy-http + args: + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 8 }} + {{- end }} + - --secure-listen-address=:{{ .Values.service.port | default 8080}} + - --upstream=http://127.0.0.1:{{ $servicePort }}/ + - --proxy-endpoints-port=8888 + - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml + volumeMounts: + - name: kube-rbac-proxy-config + mountPath: /etc/kube-rbac-proxy-config + {{- with .Values.kubeRBACProxy.volumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} + image: {{ include "kubeRBACProxy.image" . }} + ports: + - containerPort: {{ .Values.service.port | default 8080}} + name: "http" + - containerPort: 8888 + name: "http-healthz" + readinessProbe: + httpGet: + scheme: HTTPS + port: 8888 + path: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.kubeRBACProxy.resources }} + resources: +{{ toYaml .Values.kubeRBACProxy.resources | indent 10 }} +{{- end }} +{{- if .Values.kubeRBACProxy.containerSecurityContext }} + securityContext: +{{ toYaml .Values.kubeRBACProxy.containerSecurityContext | indent 10 }} +{{- end }} + {{- if .Values.selfMonitor.enabled }} + - name: kube-rbac-proxy-telemetry + args: + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 8 }} + {{- end }} + - --secure-listen-address=:{{ .Values.selfMonitor.telemetryPort | default 8081 }} + - --upstream=http://127.0.0.1:{{ $telemetryPort }}/ + - --proxy-endpoints-port=8889 + - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml + volumeMounts: + - name: kube-rbac-proxy-config + mountPath: /etc/kube-rbac-proxy-config + {{- with .Values.kubeRBACProxy.volumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} + image: {{ include "kubeRBACProxy.image" . }} + ports: + - containerPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + name: "metrics" + - containerPort: 8889 + name: "metrics-healthz" + readinessProbe: + httpGet: + scheme: HTTPS + port: 8889 + path: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.kubeRBACProxy.resources }} + resources: +{{ toYaml .Values.kubeRBACProxy.resources | indent 10 }} +{{- end }} +{{- if .Values.kubeRBACProxy.containerSecurityContext }} + securityContext: +{{ toYaml .Values.kubeRBACProxy.containerSecurityContext | indent 10 }} +{{- end }} + {{- end }} + {{- end }} + {{- with .Values.containers }} + {{- toYaml . | nindent 6 }} + {{- end }} +{{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "kube-state-metrics.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} + {{- if .Values.nodeSelector }} +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + {{- if .Values.tolerations }} +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.topologySpreadConstraints | indent 8 }} + {{- end }} + {{- if or (.Values.kubeconfig.enabled) (.Values.customResourceState.enabled) (.Values.volumes) (.Values.kubeRBACProxy.enabled) }} + volumes: + {{- if .Values.kubeconfig.enabled}} + - name: kubeconfig + secret: + secretName: {{ template "kube-state-metrics.fullname" . }}-kubeconfig + {{- end }} + {{- if .Values.kubeRBACProxy.enabled}} + - name: kube-rbac-proxy-config + configMap: + name: {{ template "kube-state-metrics.fullname" . }}-rbac-config + {{- end }} + {{- if .Values.customResourceState.enabled}} + - name: customresourcestate-config + configMap: + name: {{ template "kube-state-metrics.fullname" . }}-customresourcestate-config + {{- end }} + {{- if .Values.volumes }} +{{ toYaml .Values.volumes | indent 8 }} + {{- end }} + {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/extra-manifests.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/extra-manifests.yaml new file mode 100644 index 0000000000..567f7bf329 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/kubeconfig-secret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/kubeconfig-secret.yaml new file mode 100644 index 0000000000..6af0084502 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/kubeconfig-secret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.kubeconfig.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-kubeconfig + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +type: Opaque +data: + config: '{{ .Values.kubeconfig.secret }}' +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/networkpolicy.yaml new file mode 100644 index 0000000000..309b38ec54 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/networkpolicy.yaml @@ -0,0 +1,43 @@ +{{- if and .Values.networkPolicy.enabled (eq .Values.networkPolicy.flavor "kubernetes") }} +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +spec: + {{- if .Values.networkPolicy.egress }} + ## Deny all egress by default + egress: + {{- toYaml .Values.networkPolicy.egress | nindent 4 }} + {{- end }} + ingress: + {{- if .Values.networkPolicy.ingress }} + {{- toYaml .Values.networkPolicy.ingress | nindent 4 }} + {{- else }} + ## Allow ingress on default ports by default + - ports: + - port: {{ .Values.service.port | default 8080 }} + protocol: TCP + {{- if .Values.selfMonitor.enabled }} + {{- $telemetryPort := ternary 9091 (.Values.selfMonitor.telemetryPort | default 8081) .Values.kubeRBACProxy.enabled}} + - port: {{ $telemetryPort }} + protocol: TCP + {{- end }} + {{- end }} + podSelector: + {{- if .Values.networkPolicy.podSelector }} + {{- toYaml .Values.networkPolicy.podSelector | nindent 4 }} + {{- else }} + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + {{- end }} + policyTypes: + - Ingress + - Egress +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/pdb.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/pdb.yaml new file mode 100644 index 0000000000..3771b511de --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/pdb.yaml @@ -0,0 +1,18 @@ +{{- if .Values.podDisruptionBudget -}} +{{ if $.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" -}} +apiVersion: policy/v1 +{{- else -}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "kube-state-metrics.name" . }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/podsecuritypolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000000..8905e113e8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/podsecuritypolicy.yaml @@ -0,0 +1,39 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +{{- if .Values.podSecurityPolicy.annotations }} + annotations: +{{ toYaml .Values.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + volumes: + - 'secret' +{{- if .Values.podSecurityPolicy.additionalVolumes }} +{{ toYaml .Values.podSecurityPolicy.additionalVolumes | indent 4 }} +{{- end }} + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrole.yaml new file mode 100644 index 0000000000..654e4a3d57 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: psp-{{ template "kube-state-metrics.fullname" . }} +rules: +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} +- apiGroups: ['policy'] +{{- else }} +- apiGroups: ['extensions'] +{{- end }} + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-state-metrics.fullname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..5b62a18bdf --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.podSecurityPolicy.enabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: psp-{{ template "kube-state-metrics.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: psp-{{ template "kube-state-metrics.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/rbac-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/rbac-configmap.yaml new file mode 100644 index 0000000000..671dc9d660 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/rbac-configmap.yaml @@ -0,0 +1,22 @@ +{{- if .Values.kubeRBACProxy.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-rbac-config + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: + {{ toYaml .Values.annotations | nindent 4 }} + {{- end }} +data: + config-file.yaml: |+ + authorization: + resourceAttributes: + namespace: {{ template "kube-state-metrics.namespace" . }} + apiVersion: v1 + resource: services + subresource: {{ template "kube-state-metrics.fullname" . }} + name: {{ template "kube-state-metrics.fullname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/role.yaml new file mode 100644 index 0000000000..0170878376 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/role.yaml @@ -0,0 +1,215 @@ +{{- if not (kindIs "slice" .Values.collectors) }} +{{- fail "Collectors need to be a List since kube-state-metrics chart 3.2.2. Please check README for more information."}} +{{- end }} +{{- if and (eq .Values.rbac.create true) (not .Values.rbac.useExistingRole) -}} +{{- range (ternary (join "," .Values.namespaces | split "," ) (list "") (eq $.Values.rbac.useClusterRole false)) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +{{- if eq $.Values.rbac.useClusterRole false }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + labels: + {{- include "kube-state-metrics.labels" $ | indent 4 }} + name: {{ template "kube-state-metrics.fullname" $ }} +{{- if eq $.Values.rbac.useClusterRole false }} + namespace: {{ . }} +{{- end }} +rules: +{{ if has "certificatesigningrequests" $.Values.collectors }} +- apiGroups: ["certificates.k8s.io"] + resources: + - certificatesigningrequests + verbs: ["list", "watch"] +{{ end -}} +{{ if has "configmaps" $.Values.collectors }} +- apiGroups: [""] + resources: + - configmaps + verbs: ["list", "watch"] +{{ end -}} +{{ if has "cronjobs" $.Values.collectors }} +- apiGroups: ["batch"] + resources: + - cronjobs + verbs: ["list", "watch"] +{{ end -}} +{{ if has "daemonsets" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - daemonsets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "deployments" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - deployments + verbs: ["list", "watch"] +{{ end -}} +{{ if has "endpoints" $.Values.collectors }} +- apiGroups: [""] + resources: + - endpoints + verbs: ["list", "watch"] +{{ end -}} +{{ if has "endpointslices" $.Values.collectors }} +- apiGroups: ["discovery.k8s.io"] + resources: + - endpointslices + verbs: ["list", "watch"] +{{ end -}} +{{ if has "horizontalpodautoscalers" $.Values.collectors }} +- apiGroups: ["autoscaling"] + resources: + - horizontalpodautoscalers + verbs: ["list", "watch"] +{{ end -}} +{{ if has "ingresses" $.Values.collectors }} +- apiGroups: ["extensions", "networking.k8s.io"] + resources: + - ingresses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "jobs" $.Values.collectors }} +- apiGroups: ["batch"] + resources: + - jobs + verbs: ["list", "watch"] +{{ end -}} +{{ if has "leases" $.Values.collectors }} +- apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: ["list", "watch"] +{{ end -}} +{{ if has "limitranges" $.Values.collectors }} +- apiGroups: [""] + resources: + - limitranges + verbs: ["list", "watch"] +{{ end -}} +{{ if has "mutatingwebhookconfigurations" $.Values.collectors }} +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - mutatingwebhookconfigurations + verbs: ["list", "watch"] +{{ end -}} +{{ if has "namespaces" $.Values.collectors }} +- apiGroups: [""] + resources: + - namespaces + verbs: ["list", "watch"] +{{ end -}} +{{ if has "networkpolicies" $.Values.collectors }} +- apiGroups: ["networking.k8s.io"] + resources: + - networkpolicies + verbs: ["list", "watch"] +{{ end -}} +{{ if has "nodes" $.Values.collectors }} +- apiGroups: [""] + resources: + - nodes + verbs: ["list", "watch"] +{{ end -}} +{{ if has "persistentvolumeclaims" $.Values.collectors }} +- apiGroups: [""] + resources: + - persistentvolumeclaims + verbs: ["list", "watch"] +{{ end -}} +{{ if has "persistentvolumes" $.Values.collectors }} +- apiGroups: [""] + resources: + - persistentvolumes + verbs: ["list", "watch"] +{{ end -}} +{{ if has "poddisruptionbudgets" $.Values.collectors }} +- apiGroups: ["policy"] + resources: + - poddisruptionbudgets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "pods" $.Values.collectors }} +- apiGroups: [""] + resources: + - pods + verbs: ["list", "watch"] +{{ end -}} +{{ if has "replicasets" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - replicasets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "replicationcontrollers" $.Values.collectors }} +- apiGroups: [""] + resources: + - replicationcontrollers + verbs: ["list", "watch"] +{{ end -}} +{{ if has "resourcequotas" $.Values.collectors }} +- apiGroups: [""] + resources: + - resourcequotas + verbs: ["list", "watch"] +{{ end -}} +{{ if has "secrets" $.Values.collectors }} +- apiGroups: [""] + resources: + - secrets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "services" $.Values.collectors }} +- apiGroups: [""] + resources: + - services + verbs: ["list", "watch"] +{{ end -}} +{{ if has "statefulsets" $.Values.collectors }} +- apiGroups: ["apps"] + resources: + - statefulsets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "storageclasses" $.Values.collectors }} +- apiGroups: ["storage.k8s.io"] + resources: + - storageclasses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "validatingwebhookconfigurations" $.Values.collectors }} +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - validatingwebhookconfigurations + verbs: ["list", "watch"] +{{ end -}} +{{ if has "volumeattachments" $.Values.collectors }} +- apiGroups: ["storage.k8s.io"] + resources: + - volumeattachments + verbs: ["list", "watch"] +{{ end -}} +{{- if $.Values.kubeRBACProxy.enabled }} +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] +{{- end }} +{{- if $.Values.customResourceState.enabled }} +- apiGroups: ["apiextensions.k8s.io"] + resources: + - customresourcedefinitions + verbs: ["list", "watch"] +{{- end }} +{{ if $.Values.rbac.extraRules }} +{{ toYaml $.Values.rbac.extraRules }} +{{ end }} +{{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/rolebinding.yaml new file mode 100644 index 0000000000..330651b73f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.rbac.create true) (eq .Values.rbac.useClusterRole false) -}} +{{- range (join "," $.Values.namespaces) | split "," }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" $ | indent 4 }} + name: {{ template "kube-state-metrics.fullname" $ }} + namespace: {{ . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role +{{- if (not $.Values.rbac.useExistingRole) }} + name: {{ template "kube-state-metrics.fullname" $ }} +{{- else }} + name: {{ $.Values.rbac.useExistingRole }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" $ }} + namespace: {{ template "kube-state-metrics.namespace" $ }} +{{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/service.yaml new file mode 100644 index 0000000000..90c235148f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/service.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + annotations: + {{- if .Values.prometheusScrape }} + prometheus.io/scrape: '{{ .Values.prometheusScrape }}' + {{- end }} + {{- if .Values.service.annotations }} + {{- toYaml .Values.service.annotations | nindent 4 }} + {{- end }} +spec: + type: "{{ .Values.service.type }}" + {{- if .Values.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: "http" + protocol: TCP + port: {{ .Values.service.port | default 8080}} + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + targetPort: {{ .Values.service.port | default 8080}} + {{ if .Values.selfMonitor.enabled }} + - name: "metrics" + protocol: TCP + port: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + targetPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + {{- if .Values.selfMonitor.telemetryNodePort }} + nodePort: {{ .Values.selfMonitor.telemetryNodePort }} + {{- end }} + {{ end }} +{{- if .Values.service.loadBalancerIP }} + loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" +{{- end }} +{{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if .Values.autosharding.enabled }} + clusterIP: None +{{- else if .Values.service.clusterIP }} + clusterIP: "{{ .Values.service.clusterIP }}" +{{- end }} + selector: + {{- include "kube-state-metrics.selectorLabels" . | indent 4 }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/serviceaccount.yaml new file mode 100644 index 0000000000..c302bc7ca0 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.serviceAccount.annotations | indent 4 }} +{{- end }} +{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- include "kube-state-metrics.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} +{{- end }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/servicemonitor.yaml new file mode 100644 index 0000000000..577981b080 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/servicemonitor.yaml @@ -0,0 +1,126 @@ +{{- if .Values.prometheus.monitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- with .Values.prometheus.monitor.additionalLabels }} + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} + {{- with .Values.prometheus.monitor.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} + {{- with .Values.prometheus.monitor.targetLabels }} + targetLabels: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + {{- with .Values.prometheus.monitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | indent 2 }} + {{- if .Values.prometheus.monitor.namespaceSelector }} + namespaceSelector: + matchNames: + {{- with .Values.prometheus.monitor.namespaceSelector }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + selector: + matchLabels: + {{- with .Values.prometheus.monitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + {{- end }} + endpoints: + - port: http + {{- if or .Values.prometheus.monitor.http.interval .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.http.interval | default .Values.prometheus.monitor.interval }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.scrapeTimeout .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.http.scrapeTimeout | default .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.proxyUrl .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.http.proxyUrl | default .Values.prometheus.monitor.proxyUrl }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.enableHttp2 .Values.prometheus.monitor.enableHttp2 }} + enableHttp2: {{ .Values.prometheus.monitor.http.enableHttp2 | default .Values.prometheus.monitor.enableHttp2 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.honorLabels .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + metricRelabelings: + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName }} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.metricRelabelings .Values.prometheus.monitor.metricRelabelings }} + {{- toYaml (.Values.prometheus.monitor.http.metricRelabelings | default .Values.prometheus.monitor.metricRelabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.relabelings .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml (.Values.prometheus.monitor.http.relabelings | default .Values.prometheus.monitor.relabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.scheme .Values.prometheus.monitor.scheme }} + scheme: {{ .Values.prometheus.monitor.http.scheme | default .Values.prometheus.monitor.scheme }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.tlsConfig .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml (.Values.prometheus.monitor.http.tlsConfig | default .Values.prometheus.monitor.tlsConfig) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.http.bearerTokenFile .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.monitor.http.bearerTokenFile | default .Values.prometheus.monitor.bearerTokenFile }} + {{- end }} + {{- with (.Values.prometheus.monitor.http.bearerTokenSecret | default .Values.prometheus.monitor.bearerTokenSecret) }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.selfMonitor.enabled }} + - port: metrics + {{- if or .Values.prometheus.monitor.metrics.interval .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.metrics.interval | default .Values.prometheus.monitor.interval }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.scrapeTimeout .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.metrics.scrapeTimeout | default .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.proxyUrl .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.metrics.proxyUrl | default .Values.prometheus.monitor.proxyUrl }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.enableHttp2 .Values.prometheus.monitor.enableHttp2 }} + enableHttp2: {{ .Values.prometheus.monitor.metrics.enableHttp2 | default .Values.prometheus.monitor.enableHttp2 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.honorLabels .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.relabelings .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml (.Values.prometheus.monitor.metrics.relabelings | default .Values.prometheus.monitor.relabelings) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.scheme .Values.prometheus.monitor.scheme }} + scheme: {{ .Values.prometheus.monitor.metrics.scheme | default .Values.prometheus.monitor.scheme }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.tlsConfig .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml (.Values.prometheus.monitor.metrics.tlsConfig | default .Values.prometheus.monitor.tlsConfig) | nindent 8 }} + {{- end }} + {{- if or .Values.prometheus.monitor.metrics.bearerTokenFile .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.monitor.metrics.bearerTokenFile | default .Values.prometheus.monitor.bearerTokenFile }} + {{- end }} + {{- with (.Values.prometheus.monitor.metrics.bearerTokenSecret | default .Values.prometheus.monitor.bearerTokenSecret) }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-role.yaml new file mode 100644 index 0000000000..489de147c1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-role.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.autosharding.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - apps + resourceNames: + - {{ template "kube-state-metrics.fullname" . }} + resources: + - statefulsets + verbs: + - get + - list + - watch +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml new file mode 100644 index 0000000000..73b37a4f64 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.autosharding.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml new file mode 100644 index 0000000000..f46305b517 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/templates/verticalpodautoscaler.yaml @@ -0,0 +1,44 @@ +{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.verticalPodAutoscaler.enabled) }} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +spec: + {{- with .Values.verticalPodAutoscaler.recommenders }} + recommenders: + {{- toYaml . | nindent 4 }} + {{- end }} + resourcePolicy: + containerPolicies: + - containerName: {{ template "kube-state-metrics.name" . }} + {{- with .Values.verticalPodAutoscaler.controlledResources }} + controlledResources: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.controlledValues }} + controlledValues: {{ .Values.verticalPodAutoscaler.controlledValues }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.maxAllowed }} + maxAllowed: + {{ toYaml .Values.verticalPodAutoscaler.maxAllowed | nindent 8 }} + {{- end }} + {{- if .Values.verticalPodAutoscaler.minAllowed }} + minAllowed: + {{ toYaml .Values.verticalPodAutoscaler.minAllowed | nindent 8 }} + {{- end }} + targetRef: + apiVersion: apps/v1 + {{- if .Values.autosharding.enabled }} + kind: StatefulSet + {{- else }} + kind: Deployment + {{- end }} + name: {{ template "kube-state-metrics.fullname" . }} + {{- with .Values.verticalPodAutoscaler.updatePolicy }} + updatePolicy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/values.yaml new file mode 100644 index 0000000000..ab111f8091 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kube-state-metrics/values.yaml @@ -0,0 +1,523 @@ +# Default values for kube-state-metrics. +prometheusScrape: true +image: + registry: docker.io + repository: rancher/mirrored-kube-state-metrics-kube-state-metrics + tag: v2.12.0 + sha: "" + pullPolicy: IfNotPresent + +imagePullSecrets: [] +# - name: "image-pull-secret" + +global: + cattle: + systemDefaultRegistry: "" + + # To help compatibility with other charts which use global.imagePullSecrets. + # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). + # global: + # imagePullSecrets: + # - name: pullSecret1 + # - name: pullSecret2 + # or + # global: + # imagePullSecrets: + # - pullSecret1 + # - pullSecret2 + imagePullSecrets: [] + # + # Allow parent charts to override registry hostname + imageRegistry: "" + +# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data +# will be automatically sharded across <.Values.replicas> pods using the built-in +# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding +# This is an experimental feature and there are no stability guarantees. +autosharding: + enabled: false + +replicas: 1 + +# Change the deployment strategy when autosharding is disabled. +# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +# The default is "RollingUpdate" as per Kubernetes defaults. +# During a release, 'RollingUpdate' can lead to two running instances for a short period of time while 'Recreate' can create a small gap in data. +# updateStrategy: Recreate + +# Number of old history to retain to allow rollback +# Default Kubernetes value is set to 10 +revisionHistoryLimit: 10 + +# List of additional cli arguments to configure kube-state-metrics +# for example: --enable-gzip-encoding, --log-file, etc. +# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md +extraArgs: [] + +# If false then the user will opt out of automounting API credentials. +automountServiceAccountToken: true + +service: + port: 8080 + # Default to clusterIP for backward compatibility + type: ClusterIP + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + nodePort: 0 + loadBalancerIP: "" + # Only allow access to the loadBalancerIP from these IPs + loadBalancerSourceRanges: [] + clusterIP: "" + annotations: {} + +## Additional labels to add to all resources +customLabels: {} + # app: kube-state-metrics + +## Override selector labels +selectorOverride: {} + +## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box +releaseLabel: false + +hostNetwork: false + +rbac: + # If true, create & use RBAC resources + create: true + + # Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here. + # useExistingRole: your-existing-role + + # If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to) + useClusterRole: true + + # Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration + # Example: + # - apiGroups: ["monitoring.coreos.com"] + # resources: ["prometheuses"] + # verbs: ["list", "watch"] + extraRules: [] + +# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled). +# The requests are served through the same service but requests are then HTTPS. +kubeRBACProxy: + enabled: false + image: + repository: rancher/mirrored-brancz-kube-rbac-proxy + tag: v0.18.0 + sha: "" + pullPolicy: IfNotPresent + + # List of additional cli arguments to configure kube-rbac-prxy + # for example: --tls-cipher-suites, --log-file, etc. + # all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage + extraArgs: [] + + ## Specify security settings for a Container + ## Allows overrides and additional options compared to (Pod) securityContext + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + + 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: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + + ## volumeMounts enables mounting custom volumes in rbac-proxy containers + ## Useful for TLS certificates and keys + volumeMounts: [] + # - mountPath: /etc/tls + # name: kube-rbac-proxy-tls + # readOnly: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created, require rbac true + 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: + # Reference to one or more secrets to be used when pulling images + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # ServiceAccount annotations. + # Use case: AWS EKS IAM roles for service accounts + # ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html + annotations: {} + # If false then the user will opt out of automounting API credentials. + automountServiceAccountToken: true + +prometheus: + monitor: + enabled: false + annotations: {} + additionalLabels: {} + namespace: "" + namespaceSelector: [] + jobLabel: "" + targetLabels: [] + podTargetLabels: [] + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + selectorOverride: {} + + ## kube-state-metrics endpoint + http: + interval: "" + scrapeTimeout: "" + proxyUrl: "" + ## Whether to enable HTTP2 for servicemonitor + enableHttp2: false + honorLabels: false + metricRelabelings: [] + relabelings: [] + scheme: "" + ## File to read bearer token for scraping targets + bearerTokenFile: "" + ## Secret to mount to read bearer token for scraping targets. The secret needs + ## to be in the same namespace as the service monitor and accessible by the + ## Prometheus Operator + bearerTokenSecret: {} + # name: secret-name + # key: key-name + tlsConfig: {} + + ## selfMonitor endpoint + metrics: + interval: "" + scrapeTimeout: "" + proxyUrl: "" + ## Whether to enable HTTP2 for servicemonitor + enableHttp2: false + honorLabels: false + metricRelabelings: [] + relabelings: [] + scheme: "" + ## File to read bearer token for scraping targets + bearerTokenFile: "" + ## Secret to mount to read bearer token for scraping targets. The secret needs + ## to be in the same namespace as the service monitor and accessible by the + ## Prometheus Operator + bearerTokenSecret: {} + # name: secret-name + # key: key-name + tlsConfig: {} + +## Specify if a Pod Security Policy for kube-state-metrics must be created +## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## +podSecurityPolicy: + enabled: false + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + additionalVolumes: [] + +## Configure network policy for kube-state-metrics +networkPolicy: + enabled: false + # networkPolicy.flavor -- Flavor of the network policy to use. + # Can be: + # * kubernetes for networking.k8s.io/v1/NetworkPolicy + # * cilium for cilium.io/v2/CiliumNetworkPolicy + flavor: kubernetes + + ## Configure the cilium network policy kube-apiserver selector + # cilium: + # kubeApiServerSelector: + # - toEntities: + # - kube-apiserver + + # egress: + # - {} + # ingress: + # - {} + # podSelector: + # matchLabels: + # app.kubernetes.io/name: kube-state-metrics + +securityContext: + enabled: true + runAsGroup: 65534 + runAsUser: 65534 + fsGroup: 65534 + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + +## Specify security settings for a Container +## Allows overrides and additional options compared to (Pod) securityContext +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + +## Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +## Affinity settings for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +affinity: {} + +## Tolerations for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +## Topology spread constraints for pod assignment +## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +topologySpreadConstraints: [] + +# Annotations to be added to the deployment/statefulset +annotations: {} + +# Annotations to be added to the pod +podAnnotations: {} + +## Assign a PriorityClassName to pods if set +# priorityClassName: "" + +# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} + +# Comma-separated list of metrics to be exposed. +# This list comprises of exact metric names and/or regex patterns. +# The allowlist and denylist are mutually exclusive. +metricAllowlist: [] + +# Comma-separated list of metrics not to be enabled. +# This list comprises of exact metric names and/or regex patterns. +# The allowlist and denylist are mutually exclusive. +metricDenylist: [] + +# Comma-separated list of additional Kubernetes label keys that will be used in the resource's +# labels metric. By default the metric contains only name and namespace labels. +# To include additional labels, provide a list of resource names in their plural form and Kubernetes +# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. +# A single '*' can be provided per resource instead to allow any labels, but that has +# severe performance implications (Example: '=pods=[*]'). +metricLabelsAllowlist: [] + # - namespaces=[k8s-label-1,k8s-label-n] + +# Comma-separated list of Kubernetes annotations keys that will be used in the resource' +# labels metric. By default the metric contains only name and namespace labels. +# To include additional annotations provide a list of resource names in their plural form and Kubernetes +# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. +# A single '*' can be provided per resource instead to allow any annotations, but that has +# severe performance implications (Example: '=pods=[*]'). +metricAnnotationsAllowList: [] + # - pods=[k8s-annotation-1,k8s-annotation-n] + +# Available collectors for kube-state-metrics. +# By default, all available resources are enabled, comment out to disable. +collectors: + - certificatesigningrequests + - configmaps + - cronjobs + - daemonsets + - deployments + - endpoints + - horizontalpodautoscalers + - ingresses + - jobs + - leases + - limitranges + - mutatingwebhookconfigurations + - namespaces + - networkpolicies + - nodes + - persistentvolumeclaims + - persistentvolumes + - poddisruptionbudgets + - pods + - replicasets + - replicationcontrollers + - resourcequotas + - secrets + - services + - statefulsets + - storageclasses + - validatingwebhookconfigurations + - volumeattachments + +# Enabling kubeconfig will pass the --kubeconfig argument to the container +kubeconfig: + enabled: false + # base64 encoded kube-config file + secret: + +# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics +customResourceState: + enabled: false + # Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules + config: {} + +# Enable only the release namespace for collecting resources. By default all namespaces are collected. +# If releaseNamespace and namespaces are both set a merged list will be collected. +releaseNamespace: false + +# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected. +namespaces: "" + +# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, +# only namespaces that are excluded in namespaces-denylist will be used. +namespacesDenylist: "" + +## Override the deployment namespace +## +namespaceOverride: "" + +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: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + +## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role. +## For example: kubeTargetVersionOverride: 1.14.9 +## +kubeTargetVersionOverride: "" + +# Enable self metrics configuration for service and Service Monitor +# Default values for telemetry configuration can be overridden +# If you set telemetryNodePort, you must also set service.type to NodePort +selfMonitor: + enabled: false + # telemetryHost: 0.0.0.0 + # telemetryPort: 8081 + # telemetryNodePort: 0 + +# Enable vertical pod autoscaler support for kube-state-metrics +verticalPodAutoscaler: + enabled: false + + # Recommender 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: [] + # - name: custom-recommender-performance + + # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory + controlledResources: [] + # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. + # controlledValues: RequestsAndLimits + + # Define the max allowed resources for the pod + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # Define the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + + # 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 + +# volumeMounts are used to add custom volume mounts to deployment. +# See example below +volumeMounts: [] +# - mountPath: /etc/config +# name: config-volume + +# volumes are used to add custom volumes to deployment +# See example below +volumes: [] +# - configMap: +# name: cm-for-volume +# name: config-volume + +# Extra manifests to deploy as an array +extraManifests: [] + # - apiVersion: v1 + # kind: ConfigMap + # metadata: + # labels: + # name: prometheus-extra + # data: + # extra-data: "value" + +## Containers allows injecting additional containers. +containers: [] + # - name: crd-init + # image: kiwigrid/k8s-sidecar:latest + +## InitContainers allows injecting additional initContainers. +initContainers: [] + # - name: crd-sidecar + # image: kiwigrid/k8s-sidecar:latest + +## Liveness probe +## +livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + +## Readiness probe +## +readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/Chart.yaml new file mode 100644 index 0000000000..2c7102aeaa --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: kubeAdmControllerManager +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmControllerManager/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/Chart.yaml new file mode 100644 index 0000000000..5e21f46dd9 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: kubeAdmEtcd +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmEtcd/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/Chart.yaml new file mode 100644 index 0000000000..5ec8f95231 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: kubeAdmProxy +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmProxy/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/Chart.yaml new file mode 100644 index 0000000000..0d8a9da226 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: kubeAdmScheduler +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/kubeAdmScheduler/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/Chart.yaml new file mode 100644 index 0000000000..bed274d82c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/Chart.yaml @@ -0,0 +1,27 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-prometheus-adapter +apiVersion: v1 +appVersion: v0.11.2 +description: A Helm chart for k8s prometheus adapter +home: https://github.com/kubernetes-sigs/prometheus-adapter +keywords: +- hpa +- metrics +- prometheus +- adapter +maintainers: +- email: mattias.gees@jetstack.io + name: mattiasgees +- name: steven-sheehy +- email: hfernandez@mesosphere.com + name: hectorj2f +name: prometheus-adapter +sources: +- https://github.com/kubernetes/charts +- https://github.com/kubernetes-sigs/prometheus-adapter +version: 4.10.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/README.md new file mode 100644 index 0000000000..d77bb0c920 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/README.md @@ -0,0 +1,160 @@ +# Prometheus Adapter + +Installs the [Prometheus Adapter](https://github.com/kubernetes-sigs/prometheus-adapter) for the Custom Metrics API. Custom metrics are used in Kubernetes by [Horizontal Pod Autoscalers](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) to scale workloads based upon your own metric pulled from an external metrics provider like Prometheus. This chart complements the [metrics-server](https://github.com/helm/charts/tree/master/stable/metrics-server) chart that provides resource only metrics. + +## Prerequisites + +Kubernetes 1.14+ + +## Get Helm Repositories Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Helm Chart + +```console +helm install [RELEASE_NAME] prometheus-community/prometheus-adapter +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## 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._ + +## Upgrading Helm Chart + +```console +helm upgrade [RELEASE_NAME] [CHART] --install +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### To 4.2.0 + +Readiness and liveness probes are now fully configurable through values `readinessProbe` and `livenessProbe`. The previous values have been kept as defaults. + +### To 4.0.0 + +Previously, security context of the container was set directly in the deployment template. This release makes it configurable through the new configuration variable `securityContext` whilst keeping the previously set values as defaults. Furthermore, previous variable `runAsUser` is now set in `securityContext` and is not used any longer. Please, use `securityContext.runAsUser` instead. In the same security context, `seccompProfile` has been enabled and set to type `RuntimeDefault`. + +### To 3.0.0 + +Due to a change in deployment labels, the upgrade requires `helm upgrade --force` in order to re-create the deployment. + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values prometheus-community/prometheus-adapter +``` + +### Prometheus Service Endpoint + +To use the chart, ensure the `prometheus.url` and `prometheus.port` are configured with the correct Prometheus service endpoint. If Prometheus is exposed under HTTPS the host's CA Bundle must be exposed to the container using `extraVolumes` and `extraVolumeMounts`. + +### Adapter Rules + +Additionally, the chart comes with a set of default rules out of the box but they may pull in too many metrics or not map them correctly for your needs. Therefore, it is recommended to populate `rules.custom` with a list of rules (see the [config document](https://github.com/kubernetes-sigs/prometheus-adapter/blob/master/docs/config.md) for the proper format). + +### Horizontal Pod Autoscaler Metrics + +Finally, to configure your Horizontal Pod Autoscaler to use the custom metric, see the custom metrics section of the [HPA walkthrough](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics). + +The Prometheus Adapter can serve three different [metrics APIs](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis): + +### Custom Metrics + +Enabling this option will cause custom metrics to be served at `/apis/custom.metrics.k8s.io/v1beta1`. Enabled by default when `rules.default` is true, but can be customized by populating `rules.custom`: + +```yaml +rules: + custom: + - seriesQuery: '{__name__=~"^some_metric_count$"}' + resources: + template: <<.Resource>> + name: + matches: "" + as: "my_custom_metric" + metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) +``` + +### External Metrics + +Enabling this option will cause external metrics to be served at `/apis/external.metrics.k8s.io/v1beta1`. Can be enabled by populating `rules.external`: + +```yaml +rules: + external: + - seriesQuery: '{__name__=~"^some_metric_count$"}' + resources: + template: <<.Resource>> + name: + matches: "" + as: "my_external_metric" + metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) +``` + +### Resource Metrics + +Enabling this option will cause resource metrics to be served at `/apis/metrics.k8s.io/v1beta1`. Resource metrics will allow pod CPU and Memory metrics to be used in [Horizontal Pod Autoscalers](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) as well as the `kubectl top` command. Can be enabled by populating `rules.resource`: + +```yaml +rules: + resource: + cpu: + containerQuery: | + sum by (<<.GroupBy>>) ( + rate(container_cpu_usage_seconds_total{container!="",<<.LabelMatchers>>}[3m]) + ) + nodeQuery: | + sum by (<<.GroupBy>>) ( + rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal",<<.LabelMatchers>>}[3m]) + ) + resources: + overrides: + node: + resource: node + namespace: + resource: namespace + pod: + resource: pod + containerLabel: container + memory: + containerQuery: | + sum by (<<.GroupBy>>) ( + avg_over_time(container_memory_working_set_bytes{container!="",<<.LabelMatchers>>}[3m]) + ) + nodeQuery: | + sum by (<<.GroupBy>>) ( + avg_over_time(node_memory_MemTotal_bytes{<<.LabelMatchers>>}[3m]) + - + avg_over_time(node_memory_MemAvailable_bytes{<<.LabelMatchers>>}[3m]) + ) + resources: + overrides: + node: + resource: node + namespace: + resource: namespace + pod: + resource: pod + containerLabel: container + window: 3m +``` + +**NOTE:** Setting a value for `rules.resource` will also deploy the resource metrics API service, providing the same functionality as [metrics-server](https://github.com/helm/charts/tree/master/stable/metrics-server). As such it is not possible to deploy them both in the same cluster. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/NOTES.txt new file mode 100644 index 0000000000..b7b9b99322 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/NOTES.txt @@ -0,0 +1,9 @@ +{{ template "k8s-prometheus-adapter.fullname" . }} has been deployed. +In a few minutes you should be able to list metrics using the following command(s): +{{ if .Values.rules.resource }} + kubectl get --raw /apis/metrics.k8s.io/v1beta1 +{{- end }} + kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 +{{ if .Values.rules.external }} + kubectl get --raw /apis/external.metrics.k8s.io/v1beta1 +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/_helpers.tpl new file mode 100644 index 0000000000..edbb829b2b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/_helpers.tpl @@ -0,0 +1,113 @@ +# Rancher +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "k8s-prometheus-adapter.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 "k8s-prometheus-adapter.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 -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "k8s-prometheus-adapter.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "k8s-prometheus-adapter.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Generate basic labels +*/}} +{{- define "k8s-prometheus-adapter.labels" }} +helm.sh/chart: {{ include "k8s-prometheus-adapter.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: metrics +app.kubernetes.io/part-of: {{ template "k8s-prometheus-adapter.name" . }} +{{- include "k8s-prometheus-adapter.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "k8s-prometheus-adapter.selectorLabels" }} +app.kubernetes.io/name: {{ include "k8s-prometheus-adapter.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "k8s-prometheus-adapter.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "k8s-prometheus-adapter.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* Get Policy API Version */}} +{{- define "k8s-prometheus-adapter.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/certmanager.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/certmanager.yaml new file mode 100644 index 0000000000..4e32c964c6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/certmanager.yaml @@ -0,0 +1,76 @@ +{{- if .Values.certManager.enabled -}} +--- +# Create a selfsigned Issuer, in order to create a root CA certificate for +# signing webhook serving certificates +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ template "k8s-prometheus-adapter.fullname" . }}-self-signed-issuer + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} +spec: + selfSigned: {} +--- +# Generate a CA Certificate used to sign certificates for the webhook +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "k8s-prometheus-adapter.fullname" . }}-root-cert + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} +spec: + secretName: {{ template "k8s-prometheus-adapter.fullname" . }}-root-cert + duration: {{ .Values.certManager.caCertDuration }} + issuerRef: + name: {{ template "k8s-prometheus-adapter.fullname" . }}-self-signed-issuer + commonName: "ca.webhook.prometheus-adapter" + isCA: true +--- +# Create an Issuer that uses the above generated CA certificate to issue certs +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ template "k8s-prometheus-adapter.fullname" . }}-root-issuer + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} +spec: + ca: + secretName: {{ template "k8s-prometheus-adapter.fullname" . }}-root-cert +--- +# Finally, generate a serving certificate for the apiservices to use +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "k8s-prometheus-adapter.fullname" . }}-cert + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} +spec: + secretName: {{ template "k8s-prometheus-adapter.fullname" . }} + duration: {{ .Values.certManager.certDuration }} + issuerRef: + name: {{ template "k8s-prometheus-adapter.fullname" . }}-root-issuer + dnsNames: + - {{ template "k8s-prometheus-adapter.fullname" . }} + - {{ template "k8s-prometheus-adapter.fullname" . }}.{{ include "k8s-prometheus-adapter.namespace" . }} + - {{ template "k8s-prometheus-adapter.fullname" . }}.{{ include "k8s-prometheus-adapter.namespace" . }}.svc +{{- end -}} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml new file mode 100644 index 0000000000..6701e6ba08 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-delegator.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-system-auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-reader.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-reader.yaml new file mode 100644 index 0000000000..fe13048847 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-auth-reader.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create .Values.rbac.useAuthReaderClusterRole -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-auth-reader +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml new file mode 100644 index 0000000000..67efd2aa2f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-binding-resource-reader.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-resource-reader +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "k8s-prometheus-adapter.name" . }}-resource-reader +subjects: +- kind: ServiceAccount + name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml new file mode 100644 index 0000000000..2c690a03cc --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/cluster-role-resource-reader.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-resource-reader +rules: +- apiGroups: + - "" + resources: + - namespaces + - pods + - services + - configmaps + verbs: + - get + - list + - watch +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/configmap.yaml new file mode 100644 index 0000000000..17f415d970 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/configmap.yaml @@ -0,0 +1,97 @@ +{{- if not .Values.rules.existing -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "k8s-prometheus-adapter.fullname" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} +data: + config.yaml: | +{{- if or .Values.rules.default .Values.rules.custom }} + rules: +{{- if .Values.rules.default }} + - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' + seriesFilters: [] + resources: + overrides: + namespace: + resource: namespace + pod: + resource: pod + name: + matches: ^container_(.*)_seconds_total$ + as: "" + metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[5m])) + by (<<.GroupBy>>) + - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' + seriesFilters: + - isNot: ^container_.*_seconds_total$ + resources: + overrides: + namespace: + resource: namespace + pod: + resource: pod + name: + matches: ^container_(.*)_total$ + as: "" + metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[5m])) + by (<<.GroupBy>>) + - seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}' + seriesFilters: + - isNot: ^container_.*_total$ + resources: + overrides: + namespace: + resource: namespace + pod: + resource: pod + name: + matches: ^container_(.*)$ + as: "" + metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>,container!="POD"}) by (<<.GroupBy>>) + - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' + seriesFilters: + - isNot: .*_total$ + resources: + template: <<.Resource>> + name: + matches: "" + as: "" + metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) + - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' + seriesFilters: + - isNot: .*_seconds_total + resources: + template: <<.Resource>> + name: + matches: ^(.*)_total$ + as: "" + metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>) + - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' + seriesFilters: [] + resources: + template: <<.Resource>> + name: + matches: ^(.*)_seconds_total$ + as: "" + metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>) +{{- end -}} +{{- if .Values.rules.custom }} +{{ toYaml .Values.rules.custom | indent 4 }} +{{- end -}} +{{- end -}} +{{- if .Values.rules.external }} + externalRules: +{{ toYaml .Values.rules.external | indent 4 }} +{{- end -}} +{{- if .Values.rules.resource }} + resourceRules: +{{ toYaml .Values.rules.resource | indent 6 }} +{{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml new file mode 100644 index 0000000000..8b7b4e555e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-apiservice.yaml @@ -0,0 +1,34 @@ +{{- if or .Values.rules.default .Values.rules.custom }} +{{- if .Capabilities.APIVersions.Has "apiregistration.k8s.io/v1" }} +apiVersion: apiregistration.k8s.io/v1 +{{- else }} +apiVersion: apiregistration.k8s.io/v1beta1 +{{- end }} +kind: APIService +metadata: +{{- if or .Values.certManager.enabled .Values.customAnnotations }} + annotations: + certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} + cert-manager.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} + {{- if .Values.customAnnotations }} + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} +{{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: v1beta1.custom.metrics.k8s.io +spec: + service: + name: {{ template "k8s-prometheus-adapter.fullname" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} + {{- if .Values.tls.enable }} + caBundle: {{ b64enc .Values.tls.ca }} + {{- end }} + group: custom.metrics.k8s.io + version: v1beta1 + {{- if not (or .Values.tls.enable .Values.certManager.enabled) }} + insecureSkipTLSVerify: true + {{- end }} + groupPriorityMinimum: 100 + versionPriority: 100 +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml new file mode 100644 index 0000000000..0cc6920836 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role-binding-hpa.yaml @@ -0,0 +1,24 @@ +{{- /* +This if must be aligned with custom-metrics-cluster-role.yaml +as otherwise this binding will point to not existing role. +*/ -}} +{{- if and .Values.rbac.create (or .Values.rules.default .Values.rules.custom) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-hpa-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "k8s-prometheus-adapter.name" . }}-server-resources +subjects: +- kind: ServiceAccount + name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml new file mode 100644 index 0000000000..f441e1bdb6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/custom-metrics-cluster-role.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.rbac.create (or .Values.rules.default .Values.rules.custom) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-server-resources +rules: +- apiGroups: + - custom.metrics.k8s.io + resources: {{ toYaml .Values.rbac.customMetrics.resources | nindent 2 }} + verbs: ["*"] +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/deployment.yaml new file mode 100644 index 0000000000..03267b5e3b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/deployment.yaml @@ -0,0 +1,151 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- if or .Values.customAnnotations .Values.deploymentAnnotations }} + annotations: + {{- with .Values.customAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.deploymentAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.fullname" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} +spec: + replicas: {{ .Values.replicas }} + strategy: {{ toYaml .Values.strategy | nindent 4 }} + selector: + matchLabels: + {{- include "k8s-prometheus-adapter.selectorLabels" . | indent 6 }} + template: + metadata: + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | trim | nindent 8 }} + {{- end }} + name: {{ template "k8s-prometheus-adapter.name" . }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.customAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + {{- if .Values.hostNetwork.enabled }} + hostNetwork: true + {{- end }} + {{- if .Values.dnsPolicy }} + dnsPolicy: {{ .Values.dnsPolicy }} + {{- end}} + {{- with .Values.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.env }} + env: + {{- toYaml . | nindent 8 }} + {{- end }} + args: + - /adapter + - --secure-port={{ .Values.listenPort }} + {{- if or .Values.tls.enable .Values.certManager.enabled }} + - --tls-cert-file=/var/run/serving-cert/tls.crt + - --tls-private-key-file=/var/run/serving-cert/tls.key + {{- end }} + - --cert-dir=/tmp/cert + - --prometheus-url={{ tpl .Values.prometheus.url . }}{{ if .Values.prometheus.port }}:{{ .Values.prometheus.port }}{{end}}{{ .Values.prometheus.path }} + - --metrics-relist-interval={{ .Values.metricsRelistInterval }} + - --v={{ .Values.logLevel }} + - --config=/etc/adapter/config.yaml + {{- if .Values.extraArguments }} + {{- toYaml .Values.extraArguments | trim | nindent 8 }} + {{- end }} + ports: + - containerPort: {{ .Values.listenPort }} + name: https + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.startupProbe }} + startupProbe: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if .Values.resources }} + resources: + {{- toYaml .Values.resources | nindent 10 }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 10 }} + {{- end }} + volumeMounts: + {{- if .Values.extraVolumeMounts }} + {{ toYaml .Values.extraVolumeMounts | trim | nindent 8 }} + {{ end }} + - mountPath: /etc/adapter/ + name: config + readOnly: true + - mountPath: /tmp + name: tmp + {{- if or .Values.tls.enable .Values.certManager.enabled }} + - mountPath: /var/run/serving-cert + name: volume-serving-cert + readOnly: true + {{- end }} + {{- with .Values.extraContainers }} + {{- toYaml . | nindent 6 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + topologySpreadConstraints: + {{- toYaml .Values.topologySpreadConstraints | nindent 8 }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- if .Values.podSecurityContext }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.tolerations }} +{{- toYaml .Values.tolerations | nindent 8 }} +{{- end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + volumes: + {{- if .Values.extraVolumes }} + {{ toYaml .Values.extraVolumes | trim | nindent 6 }} + {{ end }} + - name: config + configMap: + name: {{ .Values.rules.existing | default (include "k8s-prometheus-adapter.fullname" . ) }} + - name: tmp + emptyDir: {} + {{- if or .Values.tls.enable .Values.certManager.enabled }} + - name: volume-serving-cert + secret: + secretName: {{ template "k8s-prometheus-adapter.fullname" . }} + {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml new file mode 100644 index 0000000000..21339af128 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-apiservice.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rules.external }} +{{- if .Capabilities.APIVersions.Has "apiregistration.k8s.io/v1" }} +apiVersion: apiregistration.k8s.io/v1 +{{- else }} +apiVersion: apiregistration.k8s.io/v1beta1 +{{- end }} +kind: APIService +metadata: +{{- if or .Values.certManager.enabled .Values.customAnnotations }} + annotations: + certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} + cert-manager.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} + {{- if .Values.customAnnotations }} + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} +{{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: v1beta1.external.metrics.k8s.io +spec: + service: + name: {{ template "k8s-prometheus-adapter.fullname" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} + {{- if .Values.tls.enable }} + caBundle: {{ b64enc .Values.tls.ca }} + {{- end }} + group: external.metrics.k8s.io + version: v1beta1 + {{- if not (or .Values.tls.enable .Values.certManager.enabled) }} + insecureSkipTLSVerify: true + {{- end }} + groupPriorityMinimum: 100 + versionPriority: 100 +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml new file mode 100644 index 0000000000..05547bd323 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role-binding-hpa.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create .Values.rules.external -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-hpa-controller-external-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "k8s-prometheus-adapter.name" . }}-external-metrics +subjects: +- kind: ServiceAccount + name: horizontal-pod-autoscaler + namespace: kube-system +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml new file mode 100644 index 0000000000..71783fd4b2 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/external-metrics-cluster-role.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create .Values.rules.external -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-external-metrics +rules: +- apiGroups: + - "external.metrics.k8s.io" + resources: {{ toYaml .Values.rbac.externalMetrics.resources | nindent 2 }} + verbs: + - list + - get + - watch +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/pdb.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/pdb.yaml new file mode 100644 index 0000000000..205761a9f1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/pdb.yaml @@ -0,0 +1,23 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: {{ include "k8s-prometheus-adapter.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ template "k8s-prometheus-adapter.fullname" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "k8s-prometheus-adapter.selectorLabels" . | indent 6 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/psp.yaml new file mode 100644 index 0000000000..ec26af502c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/psp.yaml @@ -0,0 +1,66 @@ +{{- if and .Values.psp.create (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "k8s-prometheus-adapter.fullname" . }} + {{- with (merge .Values.customAnnotations .Values.psp.annotations) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} +spec: + {{- if .Values.hostNetwork.enabled }} + hostNetwork: true + hostPorts: + - min: {{ .Values.listenPort }} + max: {{ .Values.listenPort }} + {{- end }} + fsGroup: + rule: RunAsAny + runAsGroup: + rule: RunAsAny + runAsUser: + rule: MustRunAs + ranges: + - min: 1024 + max: 65535 + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - secret + - emptyDir + - configMap +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-psp +rules: +- apiGroups: + - 'policy' + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "k8s-prometheus-adapter.fullname" . }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-psp +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "k8s-prometheus-adapter.name" . }}-psp +subjects: +- kind: ServiceAccount + name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml new file mode 100644 index 0000000000..0cc9fff6a2 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-apiservice.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rules.resource}} +{{- if .Capabilities.APIVersions.Has "apiregistration.k8s.io/v1" }} +apiVersion: apiregistration.k8s.io/v1 +{{- else }} +apiVersion: apiregistration.k8s.io/v1beta1 +{{- end }} +kind: APIService +metadata: +{{- if or .Values.certManager.enabled .Values.customAnnotations }} + annotations: + certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} + cert-manager.io/inject-ca-from: {{ printf "%s/%s-root-cert" (include "k8s-prometheus-adapter.namespace" .) (include "k8s-prometheus-adapter.fullname" .) | quote }} + {{- if .Values.customAnnotations }} + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} +{{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: v1beta1.metrics.k8s.io +spec: + service: + name: {{ template "k8s-prometheus-adapter.fullname" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} + {{- if .Values.tls.enable }} + caBundle: {{ b64enc .Values.tls.ca }} + {{- end }} + group: metrics.k8s.io + version: v1beta1 + {{- if not (or .Values.tls.enable .Values.certManager.enabled) }} + insecureSkipTLSVerify: true + {{- end }} + groupPriorityMinimum: 100 + versionPriority: 100 +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml new file mode 100644 index 0000000000..3c247e48d2 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role-binding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create .Values.rules.resource -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-hpa-controller-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "k8s-prometheus-adapter.name" . }}-metrics +subjects: +- kind: ServiceAccount + name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml new file mode 100644 index 0000000000..73d8953046 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/resource-metrics-cluster-role.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.rbac.create .Values.rules.resource -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-metrics +rules: +- apiGroups: + - "" + resources: + - pods + - nodes + - nodes/stats + verbs: + - get + - list + - watch +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml new file mode 100644 index 0000000000..f01997e62d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/role-binding-auth-reader.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.rbac.create (not .Values.rbac.useAuthReaderClusterRole) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.name" . }}-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . | quote }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/secret.yaml new file mode 100644 index 0000000000..3e7e8887bd --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/secret.yaml @@ -0,0 +1,17 @@ +{{- if .Values.tls.enable -}} +apiVersion: v1 +kind: Secret +metadata: + {{- if .Values.customAnnotations }} + annotations: + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.fullname" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} +type: kubernetes.io/tls +data: + tls.crt: {{ b64enc .Values.tls.certificate }} + tls.key: {{ b64enc .Values.tls.key }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/service.yaml new file mode 100644 index 0000000000..4879385ebc --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/service.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Service +metadata: + {{- if or .Values.service.annotations .Values.customAnnotations }} + annotations: + {{- if .Values.service.annotations }} + {{ toYaml .Values.service.annotations | indent 4 }} + {{- end }} + {{- if .Values.customAnnotations }} + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} + {{- end }} + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.fullname" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} +spec: +{{- if .Values.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} +{{- end }} + ports: + - port: {{ .Values.service.port }} + name: https + protocol: TCP + targetPort: https + selector: + {{- include "k8s-prometheus-adapter.selectorLabels" . | indent 4 }} + type: {{ .Values.service.type }} + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/serviceaccount.yaml new file mode 100644 index 0000000000..30a169ae0e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "k8s-prometheus-adapter.labels" . | indent 4 }} + name: {{ template "k8s-prometheus-adapter.serviceAccountName" . }} + namespace: {{ include "k8s-prometheus-adapter.namespace" . }} +{{- if or .Values.serviceAccount.annotations .Values.customAnnotations }} + annotations: + {{- if .Values.serviceAccount.annotations }} + {{- toYaml .Values.serviceAccount.annotations | nindent 4 }} + {{- end }} + {{- if .Values.customAnnotations }} + {{- toYaml .Values.customAnnotations | nindent 4 }} + {{- end }} +{{- end }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/values.yaml new file mode 100644 index 0000000000..e3eeb388a0 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-adapter/values.yaml @@ -0,0 +1,292 @@ +affinity: {} + +topologySpreadConstraints: [] + +image: + repository: rancher/mirrored-prometheus-adapter-prometheus-adapter + # if not set appVersion field from Chart.yaml is used + tag: v0.12.0 + pullPolicy: IfNotPresent + +logLevel: 4 + +metricsRelistInterval: 1m + +listenPort: 6443 + +nodeSelector: {} + +priorityClassName: "" + +## Override the release namespace (for multi-namespace deployments in combined charts) +namespaceOverride: "" + +## Additional annotations to add to all resources +customAnnotations: {} + # role: custom-metrics + +## Additional labels to add to all resources +customLabels: {} + # monitoring: prometheus-adapter + +# Url to access prometheus +prometheus: + # Value is templated + url: http://prometheus.default.svc + port: 9090 + path: "" + +replicas: 1 + +# k8s 1.21 needs fsGroup to be set for non root deployments +# ref: https://github.com/kubernetes/kubernetes/issues/70679 +podSecurityContext: + fsGroup: 10001 + +# SecurityContext of the container +# ref. https://kubernetes.io/docs/tasks/configure-pod-container/security-context +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 10001 + seccompProfile: + type: RuntimeDefault + +rbac: + # Specifies whether RBAC resources should be created + create: true + # Specifies if a Cluster Role should be used for the Auth Reader + useAuthReaderClusterRole: false + externalMetrics: + resources: ["*"] + customMetrics: + resources: ["*"] + +psp: + # Specifies whether PSP resources should be created + create: false + # Annotations added to the pod security policy + annotations: {} + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + +serviceAccount: + # 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: + # ServiceAccount annotations. + # Use case: AWS EKS IAM roles for service accounts + # ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html + annotations: {} + +# Custom DNS configuration to be added to prometheus-adapter pods +dnsConfig: {} + # nameservers: + # - 1.2.3.4 + # searches: + # - ns1.svc.cluster-domain.example + # - my.dns.search.suffix + # options: + # - name: ndots + # value: "2" + # - name: edns0 + +resources: {} + # requests: + # cpu: 100m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + +# Configure liveness probe +# https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#Probe +livenessProbe: + httpGet: + path: /healthz + port: https + scheme: HTTPS + initialDelaySeconds: 30 + timeoutSeconds: 5 + +# Configure readiness probe +readinessProbe: + httpGet: + path: /healthz + port: https + scheme: HTTPS + initialDelaySeconds: 30 + timeoutSeconds: 5 + +# Configure startup probe +# Use if prometheus-adapter takes a long time to finish startup e.g. polling a lot of API versions in cluster +startupProbe: {} + +rules: + default: true + + custom: [] + # - seriesQuery: '{__name__=~"^some_metric_count$"}' + # resources: + # template: <<.Resource>> + # name: + # matches: "" + # as: "my_custom_metric" + # metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) + + # Mounts a configMap with pre-generated rules for use. Overrides the + # default, custom, external and resource entries + existing: + + external: [] + # - seriesQuery: '{__name__=~"^some_metric_count$"}' + # resources: + # template: <<.Resource>> + # name: + # matches: "" + # as: "my_external_metric" + # metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>) + + # resource: + # cpu: + # containerQuery: | + # sum by (<<.GroupBy>>) ( + # rate(container_cpu_usage_seconds_total{container!="",<<.LabelMatchers>>}[3m]) + # ) + # nodeQuery: | + # sum by (<<.GroupBy>>) ( + # rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal",<<.LabelMatchers>>}[3m]) + # ) + # resources: + # overrides: + # node: + # resource: node + # namespace: + # resource: namespace + # pod: + # resource: pod + # containerLabel: container + # memory: + # containerQuery: | + # sum by (<<.GroupBy>>) ( + # avg_over_time(container_memory_working_set_bytes{container!="",<<.LabelMatchers>>}[3m]) + # ) + # nodeQuery: | + # sum by (<<.GroupBy>>) ( + # avg_over_time(node_memory_MemTotal_bytes{<<.LabelMatchers>>}[3m]) + # - + # avg_over_time(node_memory_MemAvailable_bytes{<<.LabelMatchers>>}[3m]) + # ) + # resources: + # overrides: + # node: + # resource: node + # namespace: + # resource: namespace + # pod: + # resource: pod + # containerLabel: container + # window: 3m + +service: + annotations: {} + port: 443 + type: ClusterIP + # clusterIP: 1.2.3.4 + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" +tls: + enable: false + ca: |- + # Public CA file that signed the APIService + key: |- + # Private key of the APIService + certificate: |- + # Public key of the APIService + +# Set environment variables from secrets, configmaps or by setting them as name/value +env: [] + # - name: TMP_DIR + # value: /tmp + # - name: PASSWORD + # valueFrom: + # secretKeyRef: + # name: mysecret + # key: password + # optional: false + +# Any extra arguments +extraArguments: [] + # - --tls-private-key-file=/etc/tls/tls.key + # - --tls-cert-file=/etc/tls/tls.crt + +# Additional containers to add to the pod +extraContainers: [] + +# Any extra volumes +extraVolumes: [] + # - name: example-name + # hostPath: + # path: /path/on/host + # type: DirectoryOrCreate + # - name: ssl-certs + # hostPath: + # path: /etc/ssl/certs/ca-bundle.crt + # type: File + +# Any extra volume mounts +extraVolumeMounts: [] + # - name: example-name + # mountPath: /path/in/container + # - name: ssl-certs + # mountPath: /etc/ssl/certs/ca-certificates.crt + # readOnly: true + +tolerations: [] + +# Labels added to the pod +podLabels: {} + +# Annotations added to the pod +podAnnotations: {} + +# Annotations added to the deployment +deploymentAnnotations: {} + +hostNetwork: + # Specifies if prometheus-adapter should be started in hostNetwork mode. + # + # You would require this enabled if you use alternate overlay networking for pods and + # API server unable to communicate with metrics-server. As an example, this is required + # if you use Weave network on EKS. See also dnsPolicy + enabled: false + +# When hostNetwork is enabled, you probably want to set this to ClusterFirstWithHostNet +# dnsPolicy: ClusterFirstWithHostNet + +# Deployment strategy type +strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + +podDisruptionBudget: + # Specifies if PodDisruptionBudget should be enabled + # When enabled, minAvailable or maxUnavailable should also be defined. + enabled: false + minAvailable: + maxUnavailable: 1 + +certManager: + enabled: false + caCertDuration: 43800h0m0s + certDuration: 8760h0m0s diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/Chart.yaml new file mode 100644 index 0000000000..2afcc31034 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/prometheus-community/helm-charts +apiVersion: v2 +appVersion: 1.8.2 +description: A Helm chart for prometheus node-exporter +home: https://github.com/prometheus/node_exporter/ +keywords: +- node-exporter +- prometheus +- exporter +maintainers: +- email: gianrubio@gmail.com + name: gianrubio +- email: zanhsieh@gmail.com + name: zanhsieh +- email: rootsandtrees@posteo.de + name: zeritti +name: prometheus-node-exporter +sources: +- https://github.com/prometheus/node_exporter/ +type: application +version: 4.37.1 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/README.md new file mode 100644 index 0000000000..ef83844102 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/README.md @@ -0,0 +1,96 @@ +# Prometheus Node Exporter + +Prometheus exporter for hardware and OS metrics exposed by *NIX kernels, written in Go with pluggable metric collectors. + +This chart bootstraps a Prometheus [Node Exporter](http://github.com/prometheus/node_exporter) daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Get Repository Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/prometheus-node-exporter +``` + +_See [configuration](#configuring) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall 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._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] prometheus-community/prometheus-node-exporter --install +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### 3.x to 4.x + +Starting from version 4.0.0, the `node exporter` chart is using the [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/). Therefore you have to delete the daemonset before you upgrade. + +```console +kubectl delete daemonset -l app=prometheus-node-exporter +helm upgrade -i prometheus-node-exporter prometheus-community/prometheus-node-exporter +``` + +If you use your own custom [ServiceMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor) or [PodMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#podmonitor), please ensure to upgrade their `selector` fields accordingly to the new labels. + +### From 2.x to 3.x + +Change the following: + +```yaml +hostRootFsMount: true +``` + +to: + +```yaml +hostRootFsMount: + enabled: true + mountPropagation: HostToContainer +``` + +## Configuring + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values prometheus-community/prometheus-node-exporter +``` + +### kube-rbac-proxy + +You can enable `prometheus-node-exporter` endpoint protection using `kube-rbac-proxy`. By setting `kubeRBACProxy.enabled: true`, this chart will deploy a RBAC proxy container protecting the node-exporter endpoint. +To authorize access, authenticate your requests (via a `ServiceAccount` for example) with a `ClusterRole` attached such as: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: prometheus-node-exporter-read +rules: + - apiGroups: [ "" ] + resources: ["services/node-exporter-prometheus-node-exporter"] + verbs: + - get +``` + +See [kube-rbac-proxy examples](https://github.com/brancz/kube-rbac-proxy/tree/master/examples/resource-attributes) for more details. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/NOTES.txt new file mode 100644 index 0000000000..db8584def8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/NOTES.txt @@ -0,0 +1,29 @@ +1. Get the application URL by running these commands: +{{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ template "prometheus-node-exporter.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus-node-exporter.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ template "prometheus-node-exporter.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo 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. + You can watch the status of by running 'kubectl get svc -w {{ template "prometheus-node-exporter.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ template "prometheus-node-exporter.namespace" . }} {{ template "prometheus-node-exporter.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ template "prometheus-node-exporter.namespace" . }} -l "app.kubernetes.io/name={{ template "prometheus-node-exporter.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:9100 to use your application" + kubectl port-forward --namespace {{ template "prometheus-node-exporter.namespace" . }} $POD_NAME 9100 +{{- end }} + +{{- if .Values.kubeRBACProxy.enabled}} + +kube-rbac-proxy endpoint protections is enabled: +- Metrics endpoints is now HTTPS +- Ensure that the client authenticates the requests (e.g. via service account) with the following role permissions: +``` +rules: + - apiGroups: [ "" ] + resources: ["services/{{ template "prometheus-node-exporter.fullname" . }}"] + verbs: + - get +``` +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/_helpers.tpl new file mode 100644 index 0000000000..72a6db45a1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/_helpers.tpl @@ -0,0 +1,236 @@ +# Rancher +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "prometheus-node-exporter.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 "prometheus-node-exporter.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 "prometheus-node-exporter.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "prometheus-node-exporter.labels" -}} +helm.sh/chart: {{ include "prometheus-node-exporter.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: metrics +app.kubernetes.io/part-of: {{ include "prometheus-node-exporter.name" . }} +{{ include "prometheus-node-exporter.selectorLabels" . }} +{{- with .Chart.AppVersion }} +app.kubernetes.io/version: {{ . | quote }} +{{- end }} +{{- with .Values.podLabels }} +{{ toYaml . }} +{{- end }} +{{- if .Values.releaseLabel }} +release: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "prometheus-node-exporter.selectorLabels" -}} +app.kubernetes.io/name: {{ include "prometheus-node-exporter.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "prometheus-node-exporter.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "prometheus-node-exporter.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +The image to use +*/}} +{{- define "prometheus-node-exporter.image" -}} +{{- $temp_registry := (include "system_default_registry" .) }} +{{- if .Values.image.sha }} +{{- fail "image.sha forbidden. Use image.digest instead" }} +{{- else if .Values.image.digest }} +{{- if $temp_registry }} +{{- printf "%s%s:%s@%s" $temp_registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.digest }} +{{- else if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s@%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.digest }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) .Values.image.digest }} +{{- end }} +{{- else }} +{{- if $temp_registry }} +{{- printf "%s%s:%s" $temp_registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- else if .Values.global.imageRegistry }} +{{- printf "%s/%s:%s" .Values.global.imageRegistry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default (printf "v%s" .Chart.AppVersion) .Values.image.tag) }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "prometheus-node-exporter.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Create the namespace name of the service monitor +*/}} +{{- define "prometheus-node-exporter.monitor-namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- if .Values.prometheus.monitor.namespace }} +{{- .Values.prometheus.monitor.namespace }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for servicemonitor */}} +{{- define "servicemonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end }} + +{{/* +Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) +*/}} +{{- define "prometheus-node-exporter.imagePullSecrets" -}} +{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} + {{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml . | trim }} + {{- else }} +- name: {{ . }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +Create the namespace name of the pod monitor +*/}} +{{- define "prometheus-node-exporter.podmonitor-namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- if .Values.prometheus.podMonitor.namespace }} +{{- .Values.prometheus.podMonitor.namespace }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for podmonitor */}} +{{- define "podmonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end }} + +{{/* Sets sidecar volumeMounts */}} +{{- define "prometheus-node-exporter.sidecarVolumeMounts" -}} +{{- range $_, $mount := $.Values.sidecarVolumeMount }} +- name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} +{{- end }} +{{- range $_, $mount := $.Values.sidecarHostVolumeMounts }} +- name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} +{{- if $mount.mountPropagation }} + mountPropagation: {{ $mount.mountPropagation }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/clusterrole.yaml new file mode 100644 index 0000000000..c256dba73d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and (eq .Values.rbac.create true) (eq .Values.kubeRBACProxy.enabled true) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +rules: + {{- if $.Values.kubeRBACProxy.enabled }} + - apiGroups: [ "authentication.k8s.io" ] + resources: + - tokenreviews + verbs: [ "create" ] + - apiGroups: [ "authorization.k8s.io" ] + resources: + - subjectaccessreviews + verbs: [ "create" ] + {{- end }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..653305ad9e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and (eq .Values.rbac.create true) (eq .Values.kubeRBACProxy.enabled true) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + name: {{ template "prometheus-node-exporter.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} +{{- else }} + name: {{ template "prometheus-node-exporter.fullname" . }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "prometheus-node-exporter.serviceAccountName" . }} + namespace: {{ template "prometheus-node-exporter.namespace" . }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/daemonset.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/daemonset.yaml new file mode 100644 index 0000000000..7f91a8d2b1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/daemonset.yaml @@ -0,0 +1,312 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.daemonsetAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- with .Values.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 8 }} + spec: + automountServiceAccountToken: {{ ternary true false (or .Values.serviceAccount.automountServiceAccountToken .Values.kubeRBACProxy.enabled) }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.extraInitContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "prometheus-node-exporter.serviceAccountName" . }} + {{- with .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ . }} + {{- end }} + containers: + {{- $servicePort := ternary .Values.kubeRBACProxy.port .Values.service.port .Values.kubeRBACProxy.enabled }} + - name: node-exporter + image: {{ include "prometheus-node-exporter.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - --path.procfs=/host/proc + - --path.sysfs=/host/sys + {{- if .Values.hostRootFsMount.enabled }} + - --path.rootfs=/host/root + {{- if semverCompare ">=1.4.0-0" (coalesce .Values.version .Values.image.tag .Chart.AppVersion) }} + - --path.udev.data=/host/root/run/udev/data + {{- end }} + {{- end }} + - --web.listen-address=[$(HOST_IP)]:{{ $servicePort }} + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: HOST_IP + {{- if .Values.kubeRBACProxy.enabled }} + value: 127.0.0.1 + {{- else if .Values.service.listenOnAllInterfaces }} + value: 0.0.0.0 + {{- else }} + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.hostIP + {{- end }} + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- if eq .Values.kubeRBACProxy.enabled false }} + ports: + - name: {{ .Values.service.portName }} + containerPort: {{ .Values.service.port }} + protocol: TCP + {{- end }} + livenessProbe: + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + httpGet: + {{- if .Values.kubeRBACProxy.enabled }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: / + port: {{ $servicePort }} + scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + readinessProbe: + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + {{- if .Values.kubeRBACProxy.enabled }} + host: 127.0.0.1 + {{- end }} + httpHeaders: + {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: / + port: {{ $servicePort }} + scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.terminationMessageParams.enabled }} + {{- with .Values.terminationMessageParams }} + terminationMessagePath: {{ .terminationMessagePath }} + terminationMessagePolicy: {{ .terminationMessagePolicy }} + {{- end }} + {{- end }} + volumeMounts: + - name: proc + mountPath: /host/proc + {{- with .Values.hostProcFsMount.mountPropagation }} + mountPropagation: {{ . }} + {{- end }} + readOnly: true + - name: sys + mountPath: /host/sys + {{- with .Values.hostSysFsMount.mountPropagation }} + mountPropagation: {{ . }} + {{- end }} + readOnly: true + {{- if .Values.hostRootFsMount.enabled }} + - name: root + mountPath: /host/root + {{- with .Values.hostRootFsMount.mountPropagation }} + mountPropagation: {{ . }} + {{- end }} + readOnly: true + {{- end }} + {{- range $_, $mount := .Values.extraHostVolumeMounts }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} + {{- with $mount.mountPropagation }} + mountPropagation: {{ . }} + {{- end }} + {{- end }} + {{- range $_, $mount := .Values.sidecarVolumeMount }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: true + {{- end }} + {{- range $_, $mount := .Values.configmaps }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + {{- end }} + {{- range $_, $mount := .Values.secrets }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + {{- range .Values.sidecars }} + {{- $overwrites := dict "volumeMounts" (concat (include "prometheus-node-exporter.sidecarVolumeMounts" $ | fromYamlArray) (.volumeMounts | default list) | default list) }} + {{- $defaults := dict "image" (include "prometheus-node-exporter.image" $) "securityContext" $.Values.containerSecurityContext "imagePullPolicy" $.Values.image.pullPolicy }} + - {{- toYaml (merge $overwrites . $defaults) | nindent 10 }} + {{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - name: kube-rbac-proxy + args: + {{- if .Values.kubeRBACProxy.extraArgs }} + {{- .Values.kubeRBACProxy.extraArgs | toYaml | nindent 12 }} + {{- end }} + - --secure-listen-address=:{{ .Values.service.port}} + - --upstream=http://127.0.0.1:{{ $servicePort }}/ + - --proxy-endpoints-port={{ .Values.kubeRBACProxy.proxyEndpointsPort }} + - --config-file=/etc/kube-rbac-proxy-config/config-file.yaml + volumeMounts: + - name: kube-rbac-proxy-config + mountPath: /etc/kube-rbac-proxy-config + imagePullPolicy: {{ .Values.kubeRBACProxy.image.pullPolicy }} + {{- $base_registry := (include "monitoring_registry" .) }} + {{- if .Values.kubeRBACProxy.image.sha }} + image: "{{ $base_registry | default .Values.kubeRBACProxy.image.registry}}/{{ .Values.kubeRBACProxy.image.repository }}:{{ .Values.kubeRBACProxy.image.tag }}@sha256:{{ .Values.kubeRBACProxy.image.sha }}" + {{- else }} + image: "{{ $base_registry | default .Values.kubeRBACProxy.image.registry}}/{{ .Values.kubeRBACProxy.image.repository }}:{{ .Values.kubeRBACProxy.image.tag }}" + {{- end }} + ports: + - containerPort: {{ .Values.service.port}} + name: {{ .Values.kubeRBACProxy.portName }} + {{- if .Values.kubeRBACProxy.enableHostPort }} + hostPort: {{ .Values.service.port }} + {{- end }} + - containerPort: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} + {{- if .Values.kubeRBACProxy.enableProxyEndpointsHostPort }} + hostPort: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} + {{- end }} + name: "http-healthz" + readinessProbe: + httpGet: + scheme: HTTPS + port: {{ .Values.kubeRBACProxy.proxyEndpointsPort }} + path: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.kubeRBACProxy.resources }} + resources: + {{- toYaml .Values.kubeRBACProxy.resources | nindent 12 }} + {{- end }} + {{- if .Values.terminationMessageParams.enabled }} + {{- with .Values.terminationMessageParams }} + terminationMessagePath: {{ .terminationMessagePath }} + terminationMessagePolicy: {{ .terminationMessagePolicy }} + {{- end }} + {{- end }} + {{- with .Values.kubeRBACProxy.env }} + env: + {{- range $key, $value := $.Values.kubeRBACProxy.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.kubeRBACProxy.containerSecurityContext }} + securityContext: + {{ toYaml .Values.kubeRBACProxy.containerSecurityContext | nindent 12 }} + {{- end }} + {{- end }} + {{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "prometheus-node-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} + {{- end }} + hostNetwork: {{ .Values.hostNetwork }} + hostPID: {{ .Values.hostPID }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.restartPolicy }} + restartPolicy: {{ . }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: proc + hostPath: + path: /proc + - name: sys + hostPath: + path: /sys + {{- if .Values.hostRootFsMount.enabled }} + - name: root + hostPath: + path: / + {{- end }} + {{- range $_, $mount := .Values.extraHostVolumeMounts }} + - name: {{ $mount.name }} + hostPath: + path: {{ $mount.hostPath }} + {{- with $mount.type }} + type: {{ . }} + {{- end }} + {{- end }} + {{- range $_, $mount := .Values.sidecarVolumeMount }} + - name: {{ $mount.name }} + emptyDir: + medium: Memory + {{- end }} + {{- range $_, $mount := .Values.sidecarHostVolumeMounts }} + - name: {{ $mount.name }} + hostPath: + path: {{ $mount.hostPath }} + {{- end }} + {{- range $_, $mount := .Values.configmaps }} + - name: {{ $mount.name }} + configMap: + name: {{ $mount.name }} + {{- end }} + {{- range $_, $mount := .Values.secrets }} + - name: {{ $mount.name }} + secret: + secretName: {{ $mount.name }} + {{- end }} + {{- if .Values.kubeRBACProxy.enabled }} + - name: kube-rbac-proxy-config + configMap: + name: {{ template "prometheus-node-exporter.fullname" . }}-rbac-config + {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/endpoints.yaml new file mode 100644 index 0000000000..56b695203a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/endpoints.yaml @@ -0,0 +1,18 @@ +{{- if .Values.endpoints }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +subsets: + - addresses: + {{- range .Values.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.service.portName }} + port: {{ .Values.service.port }} + protocol: TCP +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/extra-manifests.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/extra-manifests.yaml new file mode 100644 index 0000000000..2b21b71062 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl . $ }} +{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/networkpolicy.yaml new file mode 100644 index 0000000000..825722729d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/networkpolicy.yaml @@ -0,0 +1,23 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" $ | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ingress: + - ports: + - port: {{ .Values.service.port }} + policyTypes: + - Egress + - Ingress + podSelector: + matchLabels: + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/podmonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/podmonitor.yaml new file mode 100644 index 0000000000..f88da6a34e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/podmonitor.yaml @@ -0,0 +1,91 @@ +{{- if .Values.prometheus.podMonitor.enabled }} +apiVersion: {{ .Values.prometheus.podMonitor.apiVersion | default "monitoring.coreos.com/v1" }} +kind: PodMonitor +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.podmonitor-namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.prometheus.podMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.podMonitor.jobLabel }} + {{- include "podmonitor.scrapeLimits" .Values.prometheus.podMonitor | nindent 2 }} + selector: + matchLabels: + {{- with .Values.prometheus.podMonitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "prometheus-node-exporter.namespace" . }} + {{- with .Values.prometheus.podMonitor.attachMetadata }} + attachMetadata: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} + podMetricsEndpoints: + - port: {{ .Values.service.portName }} + {{- with .Values.prometheus.podMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.path }} + path: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.basicAuth }} + basicAuth: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.bearerTokenSecret }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.authorization }} + authorization: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.oauth2 }} + oauth2: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.proxyUrl }} + proxyUrl: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.honorTimestamps }} + honorTimestamps: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.honorLabels }} + honorLabels: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + enableHttp2: {{ default false .Values.prometheus.podMonitor.enableHttp2 }} + filterRunning: {{ default true .Values.prometheus.podMonitor.filterRunning }} + followRedirects: {{ default false .Values.prometheus.podMonitor.followRedirects }} + {{- with .Values.prometheus.podMonitor.params }} + params: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml new file mode 100644 index 0000000000..8957317243 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: psp-{{ include "prometheus-node-exporter.fullname" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ include "prometheus-node-exporter.fullname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..333370173b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: psp-{{ include "prometheus-node-exporter.fullname" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: psp-{{ include "prometheus-node-exporter.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp.yaml new file mode 100644 index 0000000000..4896c84daa --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/psp.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.rbac.pspAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + - 'hostPath' + hostNetwork: true + hostIPC: false + hostPID: true + hostPorts: + - min: 0 + max: 65535 + runAsUser: + # Permits the container to run with root privileges as well. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/rbac-configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/rbac-configmap.yaml new file mode 100644 index 0000000000..814e110337 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/rbac-configmap.yaml @@ -0,0 +1,16 @@ +{{- if .Values.kubeRBACProxy.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "prometheus-node-exporter.fullname" . }}-rbac-config + namespace: {{ include "prometheus-node-exporter.namespace" . }} +data: + config-file.yaml: |+ + authorization: + resourceAttributes: + namespace: {{ template "prometheus-node-exporter.namespace" . }} + apiVersion: v1 + resource: services + subresource: {{ template "prometheus-node-exporter.fullname" . }} + name: {{ template "prometheus-node-exporter.fullname" . }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/service.yaml new file mode 100644 index 0000000000..8308b7b2b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/service.yaml @@ -0,0 +1,35 @@ +{{- if .Values.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" $ | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Values.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.service.ipDualStack.ipFamilyPolicy }} +{{- end }} +{{- if .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} +{{- end }} + type: {{ .Values.service.type }} +{{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} + clusterIP: "{{ .Values.service.clusterIP }}" +{{- end }} + ports: + - port: {{ .Values.service.port }} + {{- if ( and (eq .Values.service.type "NodePort" ) (not (empty .Values.service.nodePort)) ) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + targetPort: {{ .Values.service.targetPort }} + protocol: TCP + name: {{ .Values.service.portName }} + selector: + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/serviceaccount.yaml new file mode 100644 index 0000000000..462b0cda4b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.rbac.create .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "prometheus-node-exporter.serviceAccountName" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- include "prometheus-node-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} +{{- end }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/servicemonitor.yaml new file mode 100644 index 0000000000..abe6c73c1b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/servicemonitor.yaml @@ -0,0 +1,71 @@ +{{- if .Values.prometheus.monitor.enabled }} +apiVersion: {{ .Values.prometheus.monitor.apiVersion | default "monitoring.coreos.com/v1" }} +kind: ServiceMonitor +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.monitor-namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} + {{- with .Values.prometheus.monitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | nindent 2 }} + {{- with .Values.prometheus.monitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- with .Values.prometheus.monitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }} + {{- end }} + {{- with .Values.prometheus.monitor.attachMetadata }} + attachMetadata: + {{- toYaml . | nindent 4 }} + {{- end }} + endpoints: + - port: {{ .Values.service.portName }} + scheme: {{ .Values.prometheus.monitor.scheme }} + {{- with .Values.prometheus.monitor.basicAuth }} + basicAuth: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + metricRelabelings: + {{- with .Values.prometheus.monitor.metricRelabelings }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName }} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml new file mode 100644 index 0000000000..2c2705f872 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/templates/verticalpodautoscaler.yaml @@ -0,0 +1,40 @@ +{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.verticalPodAutoscaler.enabled) }} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ include "prometheus-node-exporter.fullname" . }} + namespace: {{ include "prometheus-node-exporter.namespace" . }} + labels: + {{- include "prometheus-node-exporter.labels" . | nindent 4 }} +spec: + {{- with .Values.verticalPodAutoscaler.recommenders }} + recommenders: + {{- toYaml . | nindent 4 }} + {{- end }} + resourcePolicy: + containerPolicies: + - containerName: node-exporter + {{- with .Values.verticalPodAutoscaler.controlledResources }} + controlledResources: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.verticalPodAutoscaler.controlledValues }} + controlledValues: {{ . }} + {{- end }} + {{- with .Values.verticalPodAutoscaler.maxAllowed }} + maxAllowed: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.verticalPodAutoscaler.minAllowed }} + minAllowed: + {{- toYaml . | nindent 8 }} + {{- end }} + targetRef: + apiVersion: apps/v1 + kind: DaemonSet + name: {{ include "prometheus-node-exporter.fullname" . }} + {{- with .Values.verticalPodAutoscaler.updatePolicy }} + updatePolicy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/values.yaml new file mode 100644 index 0000000000..b02d92650a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/prometheus-node-exporter/values.yaml @@ -0,0 +1,539 @@ +# Default values for prometheus-node-exporter. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +image: + registry: docker.io + repository: rancher/mirrored-prometheus-node-exporter + # Overrides the image tag whose default is {{ printf "v%s" .Chart.AppVersion }} + tag: v1.8.2 + pullPolicy: IfNotPresent + digest: "" + +imagePullSecrets: [] +# - name: "image-pull-secret" +nameOverride: "" +fullnameOverride: "" + +# Number of old history to retain to allow rollback +# Default Kubernetes value is set to 10 +revisionHistoryLimit: 10 + +global: + cattle: + systemDefaultRegistry: "" + + # To help compatibility with other charts which use global.imagePullSecrets. + # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). + # global: + # imagePullSecrets: + # - name: pullSecret1 + # - name: pullSecret2 + # or + # global: + # imagePullSecrets: + # - pullSecret1 + # - pullSecret2 + imagePullSecrets: [] + # + # Allow parent charts to override registry hostname + imageRegistry: "" + +# Configure kube-rbac-proxy. When enabled, creates a kube-rbac-proxy to protect the node-exporter http endpoint. +# The requests are served through the same service but requests are HTTPS. +kubeRBACProxy: + enabled: false + ## Set environment variables as name/value pairs + env: {} + # VARIABLE: value + image: + registry: docker.io + repository: rancher/mirrored-brancz-kube-rbac-proxy + tag: v0.18.0 + sha: "" + pullPolicy: IfNotPresent + + # List of additional cli arguments to configure kube-rbac-proxy + # for example: --tls-cipher-suites, --log-file, etc. + # all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage + extraArgs: [] + + ## Specify security settings for a Container + ## Allows overrides and additional options compared to (Pod) securityContext + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + containerSecurityContext: {} + + # Specify the port used for the Node exporter container (upstream port) + port: 8100 + # Specify the name of the container port + portName: http + # Configure a hostPort. If true, hostPort will be enabled in the container and set to service.port. + enableHostPort: false + + # Configure Proxy Endpoints Port + # This is the port being probed for readiness + proxyEndpointsPort: 8888 + # Configure a hostPort. If true, hostPort will be enabled in the container and set to proxyEndpointsPort. + enableProxyEndpointsHostPort: false + + 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: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + +service: + enabled: true + type: ClusterIP + clusterIP: "" + port: 9796 + targetPort: 9796 + nodePort: + portName: metrics + listenOnAllInterfaces: true + annotations: + prometheus.io/scrape: "true" + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + externalTrafficPolicy: "" + +# Set a NetworkPolicy with: +# ingress only on service.port +# no egress permitted +networkPolicy: + enabled: false + +# Additional environment variables that will be passed to the daemonset +env: {} +## env: +## VARIABLE: value + +prometheus: + monitor: + enabled: false + additionalLabels: {} + namespace: "" + + jobLabel: "" + + # List of pod labels to add to node exporter metrics + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor + podTargetLabels: [] + + scheme: http + basicAuth: {} + bearerTokenFile: + tlsConfig: {} + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## Override serviceMonitor selector + ## + selectorOverride: {} + + ## Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. + ## + attachMetadata: + node: false + + relabelings: [] + metricRelabelings: [] + interval: "" + scrapeTimeout: 10s + ## prometheus.monitor.apiVersion ApiVersion for the serviceMonitor Resource(defaults to "monitoring.coreos.com/v1") + apiVersion: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + # PodMonitor defines monitoring for a set of pods. + # ref. https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor + # Using a PodMonitor may be preferred in some environments where there is very large number + # of Node Exporter endpoints (1000+) behind a single service. + # The PodMonitor is disabled by default. When switching from ServiceMonitor to PodMonitor, + # the time series resulting from the configuration through PodMonitor may have different labels. + # For instance, there will not be the service label any longer which might + # affect PromQL queries selecting that label. + podMonitor: + enabled: false + # Namespace in which to deploy the pod monitor. Defaults to the release namespace. + namespace: "" + # Additional labels, e.g. setting a label for pod monitor selector as set in prometheus + additionalLabels: {} + # release: kube-prometheus-stack + # PodTargetLabels transfers labels of the Kubernetes Pod onto the target. + podTargetLabels: [] + # apiVersion defaults to monitoring.coreos.com/v1. + apiVersion: "" + # Override pod selector to select pod objects. + selectorOverride: {} + # Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. + attachMetadata: + node: false + # The label to use to retrieve the job name from. Defaults to label app.kubernetes.io/name. + jobLabel: "" + + # Scheme/protocol to use for scraping. + scheme: "http" + # Path to scrape metrics at. + path: "/metrics" + + # BasicAuth allow an endpoint to authenticate over basic authentication. + # More info: https://prometheus.io/docs/operating/configuration/#endpoint + basicAuth: {} + # Secret to mount to read bearer token for scraping targets. + # The secret needs to be in the same namespace as the pod monitor and accessible by the Prometheus Operator. + # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secretkeyselector-v1-core + bearerTokenSecret: {} + # TLS configuration to use when scraping the endpoint. + tlsConfig: {} + # Authorization section for this endpoint. + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.SafeAuthorization + authorization: {} + # OAuth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer. + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.OAuth2 + oauth2: {} + + # ProxyURL eg http://proxyserver:2195. Directs scrapes through proxy to this endpoint. + proxyUrl: "" + # Interval at which endpoints should be scraped. If not specified Prometheus’ global scrape interval is used. + interval: "" + # Timeout after which the scrape is ended. If not specified, the Prometheus global scrape interval is used. + scrapeTimeout: "" + # HonorTimestamps controls whether Prometheus respects the timestamps present in scraped data. + honorTimestamps: true + # HonorLabels chooses the metric’s labels on collisions with target labels. + honorLabels: true + # Whether to enable HTTP2. Default false. + enableHttp2: "" + # Drop pods that are not running. (Failed, Succeeded). + # Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase + filterRunning: "" + # FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. Default false. + followRedirects: "" + # Optional HTTP URL parameters + params: {} + + # RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds + # relabelings for a few standard Kubernetes fields. The original scrape job’s name + # is available via the __tmp_prometheus_job_name label. + # More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + relabelings: [] + # MetricRelabelConfigs to apply to samples before ingestion. + metricRelabelings: [] + + # SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + sampleLimit: 0 + # TargetLimit defines a limit on the number of scraped targets that will be accepted. + targetLimit: 0 + # Per-scrape limit on number of labels that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelLimit: 0 + # Per-scrape limit on length of labels name that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelNameLengthLimit: 0 + # Per-scrape limit on length of labels value that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelValueLengthLimit: 0 + +## Customize the updateStrategy if set +updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + +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: 200m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 30Mi + +# Specify the container restart policy passed to the Node Export container +# Possible Values: Always (default)|OnFailure|Never +restartPolicy: null + +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: {} + imagePullSecrets: [] + automountServiceAccountToken: false + +securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + +containerSecurityContext: + readOnlyRootFilesystem: true + # capabilities: + # add: + # - SYS_TIME + +rbac: + ## If true, create & use RBAC resources + ## + create: true + ## If true, create & use Pod Security Policy resources + ## https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + pspEnabled: true + pspAnnotations: {} + +# for deployments that have node_exporter deployed outside of the cluster, list +# their addresses here +endpoints: [] + +# Expose the service to the host network +hostNetwork: true + +# Share the host process ID namespace +hostPID: true + +# Mount the node's root file system (/) at /host/root in the container +hostRootFsMount: + enabled: true + # Defines how new mounts in existing mounts on the node or in the container + # are propagated to the container or node, respectively. Possible values are + # None, HostToContainer, and Bidirectional. If this field is omitted, then + # None is used. More information on: + # https://kubernetes.io/docs/concepts/storage/volumes/#mount-propagation + mountPropagation: HostToContainer + +# Mount the node's proc file system (/proc) at /host/proc in the container +hostProcFsMount: + # Possible values are None, HostToContainer, and Bidirectional + mountPropagation: "" + +# Mount the node's sys file system (/sys) at /host/sys in the container +hostSysFsMount: + # Possible values are None, HostToContainer, and Bidirectional + mountPropagation: "" + +## Assign a group of affinity scheduling rules +## +affinity: {} +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchFields: +# - key: metadata.name +# operator: In +# values: +# - target-host-name + +# Annotations to be added to node exporter pods +podAnnotations: + # Fix for very slow GKE cluster upgrades + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + +# Extra labels to be added to node exporter pods +podLabels: {} + +# Annotations to be added to node exporter daemonset +daemonsetAnnotations: {} + +## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box +releaseLabel: false + +# Custom DNS configuration to be added to prometheus-node-exporter pods +dnsConfig: {} +# nameservers: +# - 1.2.3.4 +# searches: +# - ns1.svc.cluster-domain.example +# - my.dns.search.suffix +# options: +# - name: ndots +# value: "2" +# - name: edns0 + +## Assign a nodeSelector if operating a hybrid cluster +## +nodeSelector: + kubernetes.io/os: linux + # kubernetes.io/arch: amd64 + +# Specify grace period for graceful termination of pods. Defaults to 30 if null or not specified +terminationGracePeriodSeconds: null + +tolerations: + - effect: NoSchedule + operator: Exists + - effect: NoExecute + operator: Exists + +# Enable or disable container termination message settings +# https://kubernetes.io/docs/tasks/debug/debug-application/determine-reason-pod-failure/ +terminationMessageParams: + enabled: false + # If enabled, specify the path for termination messages + terminationMessagePath: /dev/termination-log + # If enabled, specify the policy for termination messages + terminationMessagePolicy: File + + +## Assign a PriorityClassName to pods if set +# priorityClassName: "" + +## Additional container arguments +## +extraArgs: [] +# - --collector.diskstats.ignored-devices=^(ram|loop|fd|(h|s|v)d[a-z]|nvme\\d+n\\d+p)\\d+$ +# - --collector.textfile.directory=/run/prometheus + +## Additional mounts from the host to node-exporter container +## +extraHostVolumeMounts: [] +# - name: +# hostPath: +# https://kubernetes.io/docs/concepts/storage/volumes/#hostpath-volume-types +# type: "" (Default)|DirectoryOrCreate|Directory|FileOrCreate|File|Socket|CharDevice|BlockDevice +# mountPath: +# readOnly: true|false +# mountPropagation: None|HostToContainer|Bidirectional + +## Additional configmaps to be mounted. +## +configmaps: [] +# - name: +# mountPath: +secrets: [] +# - name: +# mountPath: +## Override the deployment namespace +## +namespaceOverride: "" + +## Additional containers for export metrics to text file; fields image,imagePullPolicy,securityContext take default value from main container +## +sidecars: [] +# - name: nvidia-dcgm-exporter +# image: nvidia/dcgm-exporter:1.4.3 +# volumeMounts: +# - name: tmp +# mountPath: /tmp + +## Volume for sidecar containers +## +sidecarVolumeMount: [] +# - name: collector-textfiles +# mountPath: /run/prometheus +# readOnly: false + +## Additional mounts from the host to sidecar containers +## +sidecarHostVolumeMounts: [] +# - name: +# hostPath: +# mountPath: +# readOnly: true|false +# mountPropagation: None|HostToContainer|Bidirectional + +## Additional InitContainers to initialize the pod +## +extraInitContainers: [] + +## Liveness probe +## +livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + +## Readiness probe +## +readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + +# Enable vertical pod autoscaler support for prometheus-node-exporter +verticalPodAutoscaler: + enabled: false + + # Recommender 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: + # - name: custom-recommender-performance + + # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory + controlledResources: [] + # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. + # controlledValues: RequestsAndLimits + + # Define the max allowed resources for the pod + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # Define the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + + # 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 + +# Extra manifests to deploy as an array +extraManifests: [] + # - | + # apiVersion: v1 + # kind: ConfigMap + # metadata: + # name: prometheus-extra + # data: + # extra-data: "value" + +# Override version of app, required if image.tag is defined and does not follow semver +version: "" diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/Chart.yaml new file mode 100644 index 0000000000..50c3f10dcd --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rke2ControllerManager +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2ControllerManager/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/Chart.yaml new file mode 100644 index 0000000000..8a530669f5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rke2Etcd +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Etcd/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/Chart.yaml new file mode 100644 index 0000000000..d62e4a18e8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rke2IngressNginx +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2IngressNginx/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/Chart.yaml new file mode 100644 index 0000000000..2b9214f36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rke2Proxy +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Proxy/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/Chart.yaml new file mode 100644 index 0000000000..e9a8ec1dd1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rke2Scheduler +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rke2Scheduler/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/Chart.yaml new file mode 100644 index 0000000000..be2490c018 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rkeControllerManager +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeControllerManager/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/Chart.yaml new file mode 100644 index 0000000000..897ef6303d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rkeEtcd +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeEtcd/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/Chart.yaml new file mode 100644 index 0000000000..2a8ff34be7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rkeIngressNginx +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeIngressNginx/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/Chart.yaml new file mode 100644 index 0000000000..c68de64c60 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rkeProxy +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeProxy/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/Chart.yaml new file mode 100644 index 0000000000..cdb17fa2fb --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/Chart.yaml @@ -0,0 +1,15 @@ +annotations: + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>= 1.28.0-0 < 1.32.0-0' + catalog.cattle.io/os: linux + catalog.rancher.io/certified: rancher + catalog.rancher.io/namespace: cattle-monitoring-system + catalog.rancher.io/release-name: rancher-pushprox +apiVersion: v1 +appVersion: 0.1.0 +description: Sets up a deployment of the PushProx proxy and a DaemonSet of PushProx + clients. +kubeVersion: '>=1.28.0-0' +name: rkeScheduler +type: application +version: 0.2.0 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/README.md new file mode 100644 index 0000000000..345002f48a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/README.md @@ -0,0 +1,90 @@ +# rancher-pushprox + +A Rancher chart based on Rancher [PushProx](https://github.com/rancher/PushProx) that sets up a Deployment of a PushProx proxy and a DaemonSet of PushProx clients on a Kubernetes cluster. + +Installs [rancher-pushprox](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-pushprox) to create PushProx clients that can access their host's network and register with a PushProx proxy. A [Prometheus Operator](https://github.com/coreos/prometheus-operator) ServiceMonitor CR is also included that is configured to scrape the metrics from each of the clients through the proxy. + +Using an instance of this chart is suitable for the following scenarios: +- You need to scrape metrics from a port that should not be accessible outside of the host (e.g. scraping `etcd` metrics in a hardened cluster) +- You need to scrape metrics on a host that are not exposed outside of 127.0.0.1 (e.g. scraping `kube-proxy` metrics) +- You need to scrape metrics through HTTPS using certs hosted directly on `hostPath` +- You need to scrape metrics from Kubernetes components that require authorization via a service account (e.g. permissions to make request to `/metrics`) +- You need to scrape metrics without access to cacerts (i.e. enable `insecureSkipVerify`) + +The clients and proxy are created based on a Rancher fork of the [prometheus-community/PushProx](https://github.com/prometheus-community/PushProx) project. + +## Upgrading to Kubernetes v1.25+ + +Starting in Kubernetes v1.25, [Pod Security Policies](https://kubernetes.io/docs/concepts/security/pod-security-policy/) have been removed from the Kubernetes API. + +As a result, **before upgrading to Kubernetes v1.25** (or on a fresh install in a Kubernetes v1.25+ cluster), users are expected to perform an in-place upgrade of this chart with `global.cattle.psp.enabled` set to `false` if it has been previously set to `true`. +​ +> **Note:** +> In this chart release, any previous field that was associated with any PSP resources have been removed in favor of a single global field: `global.cattle.psp.enabled`. + +> **Note:** +> If you upgrade your cluster to Kubernetes v1.25+ before removing PSPs via a `helm upgrade` (even if you manually clean up resources), **it will leave the Helm release in a broken state within the cluster such that further Helm operations will not work (`helm uninstall`, `helm upgrade`, etc.).** +> +> If your charts get stuck in this state, please consult the Rancher docs on how to clean up your Helm release secrets. + +Upon setting `global.cattle.psp.enabled` to false, the chart will remove any PSP resources deployed on its behalf from the cluster. This is the default setting for this chart. + +As a replacement for PSPs, [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) should be used. Please consult the Rancher docs for more details on how to configure your chart release namespaces to work with the new Pod Security Admission and apply Pod Security Standards. + +## Configuration + +The following tables list the configurable parameters of the rancher-pushprox chart and their default values. + +### General + +#### Required +| Parameter | Description | Example | +| ----- | ----------- | ------ | +| `component` | The component that is being monitored | `kube-etcd` +| `metricsPort` | The port on the host that contains the metrics you want to scrape (e.g. `http://:/metrics`) | `2379` | +| `namespaceOverride` | The namespace to install the chart | `""` + +#### Optional +| Parameter | Description | Default | +| ----- | ----------- | ------ | +| `serviceMonitor.enabled` | Deploys a [Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor) ServiceMonitor CR that is configured to scrape metrics on the hosts that the clients are deployed on via the proxy. Also deploys a Service that points to all pods with the expected client name that exposes the `metricsPort` selected | `true` | +| `serviceMonitor.endpoints` | A list of endpoints that will be added to the ServiceMonitor based on the [Endpoint spec](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint) | `[{port: metrics}]` | +| `service.selector` | The selector that is used to populate the Service's Endpoints object. The chart will error out on rendering templating if `.Values.clients.enabled` is set alongside this field, since it is expected that this service should point to the PushProx Clients Daemonset / Deployment | `{}` | +| `clients.enabled` | Deploys a DaemonSet of clients that are each capable of scraping endpoints on the hostNetwork it is deployed on | `true` | +| `clients.port` | The port where the client will publish PushProx client-specific metrics. If deploying multiple clients onto the same node, the clients should not have conflicting ports | `9369` | +| `clients.proxyUrl` | Overrides the default proxyUrl setting of `http://pushprox-{{ .Values.component }}-proxy.{{ . Release.Namespace }}.svc.cluster.local:{{ .Values.proxy.port }}"` with the `proxyUrl` specified | `""` | +| `clients.useLocalhost` | Sets a flag on each client deployment to redirect scrapes directed to `HOST_IP` to `127.0.0.1` | `false` | +| `clients.https.enabled` | Enables scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.forceHTTPSScheme` | Forces scraping metrics via HTTPS using the provided TLS certs that exist on each host | `false` | +| `clients.https.useServiceAccountCredentials` | If set to true, the client will create a service account with permissions to scrape `/metrics` endpoint of Kubernetes components. The client will use the service account token provided to make authorized scrape requests to the Kubernetes API | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.enabled` | If set to true, the client will use service account credentials mounted at the configured path `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath`. This requires permissions to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath` | This is a volume mount on the pod with permissions to scrape `/metrics` endpoint of Kubernetes components | `"/var/run/secrets/kubernetes.io/serviceaccount/token"` | +| `clients.https.authenticationMethod.bearerTokenSecret.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components. This method is deprecated by the prometheus operator and may be removed in a future release | `false` | +| `clients.https.authenticationMethod.authorization.enabled` | If set to true, the client will use service account credentials to scrape `/metrics` endpoint of Kubernetes components | `false` | +| `clients.https.authenticationMethod.authorization.type` | If set, the client will use this type of authorization in its client requests for metrics | `"bearer"` | +| `clients.https.authenticationMethod.authorization.credentials.key` | If set, the client will use this key in the secret created by `clients.https.useServiceAccountCredentials` for authorization in its client requests for metrics | `"token"` | +| `clients.https.authenticationMethod.authorization.credentials.optional` | If set to false, the client will fail if the key in the secret created by `clients.https.useServiceAccountCredentials` does not exist | `false` | +| `clients.https.insecureSkipVerify` | If set to true, the client will disable SSL security checks | `false` | +| `clients.https.certDir` | A `hostPath` where TLS certs can be found. This path is mounted as a volume on an `initContainer` which copies only the necessary files over to an EmptyDir volume used by each client. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.certFile` | The path to the TLS cert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.keyFile` | The path to the TLS key file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.caCertFile` | The path to the TLS cacert file located within `clients.https.certDir`. Required and only used if `clients.https.enabled` is set | `""` | +| `clients.https.seLinuxOptions` | seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. | `""` | +| `clients.metrics.enabled` | Whether the client should publish PushProx client-specific metrics. | `false` | +| `clients.rbac.additionalRules` | Additional permissions to provide to the ServiceAccount bound to the client. This can be used to provide additional permissions for the client to scrape metrics from the k8s API. Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true | `[]` | +| `clients.deployment.enabled` | Deploys the client as a Deployment (generally used if the underlying hostNetwork Pod that is being scraped is managed by a Deployment) | `false` | +| `clients.deployment.replicas` | The number of pods the Deployment has, it should match the number of pod the hostNetwork Deployment has. Required and only used if `client.deployment.enable` is set | `0` | +| `clients.deployment.affinity` | The affinity rules that allocate the pod to the node in which the hostNetwork Deployment's pods run. Required and only used if `client.deployment.enable` is set | `{}` | +| `clients.resources` | Set resource limits and requests for the client container | `{}` | +| `clients.nodeSelector` | Select which nodes to deploy the clients on | `{}` | +| `clients.tolerations` | Specify tolerations for clients | `[]` | +| `proxy.enabled` | Deploys the proxy that each client will register with | `true` | +| `proxy.port` | The port exposed by the proxy that each client will register with to allow metrics to be scraped from the host | `8080` | +| `proxy.resources` | Set resource limits and requests for the proxy container | `{}` | +| `proxy.nodeSelector` | Select which nodes the proxy can be deployed on | `{}` | +| `proxy.tolerations` | Specify tolerations (if necessary) to allow the proxy to be deployed on the selected node | `[]` | +| `kubeVersionOverrides` | A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches any of the semver constraints provided as keys on the map. On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. | `[]` + +*Tip: The filepaths set in `clients.https.File` can include wildcard characters*. + +See [rancher-monitoring](https://github.com/rancher/charts/tree/gh-pages/packages/rancher-monitoring) for examples of how this chart can be used. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/_helpers.tpl new file mode 100644 index 0000000000..1ba5093944 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/_helpers.tpl @@ -0,0 +1,170 @@ +# Rancher + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# General + +{{- define "applyKubeVersionOverrides" -}} +{{- $overrides := dict -}} +{{- range $override := .Values.kubeVersionOverrides -}} +{{- if semverCompare $override.constraint $.Capabilities.KubeVersion.Version -}} +{{- $_ := mergeOverwrite $overrides $override.values -}} +{{- end -}} +{{- end -}} +{{- $_ := mergeOverwrite .Values $overrides -}} +{{- end -}} + +{{- define "pushprox.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "pushProxy.commonLabels" -}} +release: {{ .Release.Name }} +component: {{ .Values.component | quote }} +provider: kubernetes +{{- end -}} + +{{- define "pushProxy.proxyUrl" -}} +{{- $_ := (required "Template requires either .Values.proxy.port or .Values.client.proxyUrl to set proxyUrl for client" (or .Values.clients.proxyUrl .Values.proxy.port)) -}} +{{- if .Values.clients.proxyUrl -}} +{{ printf "%s" .Values.clients.proxyUrl }} +{{- else -}} +{{ printf "http://%s.%s.svc:%d" (include "pushProxy.proxy.name" .) (include "pushprox.namespace" .) (int .Values.proxy.port) }} +{{- end -}}{{- end -}} + +# Client + +{{- define "pushProxy.client.name" -}} +{{- printf "pushprox-%s-client" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.serviceAccountTokenName" -}} +{{- printf "pushprox-%s-client-service-account-token" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.client.labels" -}} +k8s-app: {{ template "pushProxy.client.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# Proxy + +{{- define "pushProxy.proxy.name" -}} +{{- printf "pushprox-%s-proxy" (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.proxy.labels" -}} +k8s-app: {{ template "pushProxy.proxy.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +# ServiceMonitor + +{{- define "pushprox.serviceMonitor.name" -}} +{{- printf "%s-%s" .Release.Name (required ".Values.component is required" .Values.component) -}} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.labels" -}} +app: {{ template "pushprox.serviceMonitor.name" . }} +{{ template "pushProxy.commonLabels" . }} +{{- end -}} + +{{- define "pushProxy.serviceMonitor.endpoints" -}} +{{- $proxyURL := (include "pushProxy.proxyUrl" .) -}} +{{- $useHTTPS := .Values.clients.https.enabled -}} +{{- $setHTTPSScheme := .Values.clients.https.forceHTTPSScheme -}} +{{- $insecureSkipVerify := .Values.clients.https.insecureSkipVerify -}} +{{- $useServiceAccountCredentials := .Values.clients.https.useServiceAccountCredentials -}} +{{- $serviceAccountTokenName := (include "pushProxy.client.serviceAccountTokenName" . ) -}} +{{- $metricRelabelings := list }} +{{- $endpoints := .Values.serviceMonitor.endpoints }} +{{- if .Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- range $endpoints }} +{{- if $.Values.proxy.enabled }} +{{- $_ := set . "proxyUrl" $proxyURL }} +{{- end }} +{{- $clusterIdRelabel := dict }} +{{- $metricRelabelings := list }} +{{- if $.Values.global.cattle.clusterId }} +{{- $_ := set $clusterIdRelabel "action" "replace" }} +{{- $_ := set $clusterIdRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterIdRelabel "targetLabel" "cluster_id" }} +{{- $_ := set $clusterIdRelabel "replacement" $.Values.global.cattle.clusterId }} +{{- $metricRelabelings = append $metricRelabelings $clusterIdRelabel }} +{{- end }} +{{- $clusterNameRelabel := dict }} +{{- if $.Values.global.cattle.clusterName }} +{{- $_ := set $clusterNameRelabel "action" "replace" }} +{{- $_ := set $clusterNameRelabel "sourceLabels" (list "__address__") }} +{{- $_ := set $clusterNameRelabel "targetLabel" "cluster_name" }} +{{- $_ := set $clusterNameRelabel "replacement" $.Values.global.cattle.clusterName }} +{{- $metricRelabelings = append $metricRelabelings $clusterNameRelabel }} +{{- end }} +{{- if not (empty $metricRelabelings) }} +{{- $_ := set . "metricRelabelings" ($metricRelabelings)}} +{{- end }} +{{- if $setHTTPSScheme -}} +{{- $_ := set . "scheme" "https" }} +{{- end -}} +{{- if $useHTTPS -}} +{{- if (hasKey . "params") }} +{{- $_ := set (get . "params") "_scheme" (list "https") }} +{{- else }} +{{- $_ := set . "params" (dict "_scheme" (list "https")) }} +{{- end }} +{{- end }} +{{- if (hasKey . "tlsConfig") }} +{{- $_ := set (get . "tlsConfig") "insecureSkipVerify" $insecureSkipVerify }} +{{- else }} +{{- $_ := set . "tlsConfig" (dict "insecureSkipVerify" $insecureSkipVerify) }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenFile.enabled }} +{{- $_ := set . "bearerTokenFile" $.Values.clients.https.authenticationMethod.bearerTokenFile.bearerTokenFilePath }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.bearerTokenSecret.enabled }} +{{- $_ := set . "bearerTokenSecret" $serviceAccountTokenName }} +{{- end }} +{{- if $.Values.clients.https.authenticationMethod.authorization.enabled }} +{{- if (hasKey . "authorization") }} +{{- $_ := set (get . "authorization") "type" $.Values.clients.https.authenticationMethod.authorization.type }} +{{- $_ := set (get . "authorization") "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional) }} +{{- else }} +{{- $_ := set . "authorization" (dict "type" $.Values.clients.https.authenticationMethod.authorization.type) }} +{{- $_ := set . "authorization" (dict "credentials" (dict "name" $serviceAccountTokenName "key" $.Values.clients.https.authenticationMethod.authorization.credentials.key "optional" $.Values.clients.https.authenticationMethod.authorization.credentials.optional)) }} +{{- end }} +{{- end }} +{{- end }} +{{- toYaml $endpoints }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml new file mode 100644 index 0000000000..a8e27c3735 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-clients-rbac.yaml @@ -0,0 +1,97 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.client.name" . }} +{{- end }} +{{- if and .Values.clients.https.enabled .Values.clients.https.useServiceAccountCredentials }} +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- if .Values.clients.rbac.additionalRules }} +{{ toYaml .Values.clients.rbac.additionalRules }} +{{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.client.name" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.client.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +--- +{{- if .Values.clients.https.useServiceAccountCredentials }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/service-account-token +metadata: + name: {{ template "pushProxy.client.serviceAccountTokenName" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + annotations: + kubernetes.io/service-account.name: {{ template "pushProxy.client.name" . }} +{{- end }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + privileged: false + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 6 }} +{{- end }} + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 0 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' +{{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + - 'emptyDir' + - 'hostPath' + allowedHostPaths: + - pathPrefix: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + readOnly: true +{{- end }} +{{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-clients.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-clients.yaml new file mode 100644 index 0000000000..e8fcfb3883 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-clients.yaml @@ -0,0 +1,157 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.clients }}{{- if .Values.clients.enabled }} +apiVersion: apps/v1 +{{- if .Values.clients.deployment.enabled }} +kind: Deployment +{{- else }} +kind: DaemonSet +{{- end }} +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} + pushprox-exporter: "client" +spec: + {{- if .Values.clients.deployment.enabled }} + replicas: {{ .Values.clients.deployment.replicas }} + {{- end }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.client.labels" . | nindent 8 }} + spec: + {{- if .Values.clients.affinity }} + affinity: {{ toYaml .Values.clients.affinity | nindent 8 }} + {{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.clients.nodeSelector }} +{{ toYaml .Values.clients.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.clients.tolerations }} +{{ toYaml .Values.clients.tolerations | indent 8 }} +{{- end }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "pushProxy.client.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-client + image: {{ template "system_default_registry" . }}{{ .Values.clients.image.repository }}:{{ .Values.clients.image.tag }} + command: + {{- range .Values.clients.command }} + - {{ . | quote }} + {{- end }} + args: + - --fqdn=$(HOST_IP) + - --proxy-url=$(PROXY_URL) + {{- if .Values.clients.metrics.enabled }} + - --metrics-addr=$(PORT) + {{- end }} + - --allow-port={{ required "Need .Values.metricsPort to configure client to be allowed to scrape metrics at port" .Values.metricsPort}} + {{- if .Values.clients.useLocalhost }} + - --use-localhost + {{- end }} + {{- if .Values.clients.https.enabled }} + {{- if .Values.clients.https.insecureSkipVerify }} + - --insecure-skip-verify + {{- end }} + {{- if .Values.clients.https.useServiceAccountCredentials }} + - --token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- if .Values.clients.https.certDir }} + - --tls.cert=/etc/ssl/push-proxy/push-proxy.pem + - --tls.key=/etc/ssl/push-proxy/push-proxy-key.pem + - --tls.cacert=/etc/ssl/push-proxy/push-proxy-ca-cert.pem + {{- end }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.clients.metrics.enabled }} + - name: PORT + value: :{{ .Values.clients.port }} + {{- end }} + - name: PROXY_URL + value: {{ template "pushProxy.proxyUrl" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + volumeMounts: + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + {{- end }} + {{- if .Values.clients.resources }} + resources: {{ toYaml .Values.clients.resources | nindent 10 }} + {{- end }} + {{- if and .Values.clients.https.enabled .Values.clients.https.certDir }} + initContainers: + - name: copy-certs + image: {{ template "system_default_registry" . }}{{ .Values.clients.copyCertsImage.repository }}:{{ .Values.clients.copyCertsImage.tag }} + command: + - sh + - -c + - | + echo "Searching for files to copy within the source volume" + echo "cert: ${CERT_FILE_NAME}" + echo "key: ${KEY_FILE_NAME}" + echo "cacert: ${CACERT_FILE_NAME}" + + CERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CERT_FILE_NAME}" | sort -r | head -n 1) + KEY_FILE_SOURCE=$(find /etc/source/ -type f -name "${KEY_FILE_NAME}" | sort -r | head -n 1) + CACERT_FILE_SOURCE=$(find /etc/source/ -type f -name "${CACERT_FILE_NAME}" | sort -r | head -n 1) + + test -z ${CERT_FILE_SOURCE} && echo "Failed to find cert file" && exit 1 + test -z ${KEY_FILE_SOURCE} && echo "Failed to find key file" && exit 1 + test -z ${CACERT_FILE_SOURCE} && echo "Failed to find cacert file" && exit 1 + + echo "Copying cert file from $CERT_FILE_SOURCE to $CERT_FILE_TARGET" + cp $CERT_FILE_SOURCE $CERT_FILE_TARGET || exit 1 + chmod 444 $CERT_FILE_TARGET || exit 1 + + echo "Copying key file from $KEY_FILE_SOURCE to $KEY_FILE_TARGET" + cp $KEY_FILE_SOURCE $KEY_FILE_TARGET || exit 1 + chmod 444 $KEY_FILE_TARGET || exit 1 + + echo "Copying cacert file from $CACERT_FILE_SOURCE to $CACERT_FILE_TARGET" + cp $CACERT_FILE_SOURCE $CACERT_FILE_TARGET || exit 1 + chmod 444 $CACERT_FILE_TARGET || exit 1 + env: + - name: CERT_FILE_NAME + value: {{ required "Need a TLS cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.certFile }} + - name: KEY_FILE_NAME + value: {{ required "Need a TLS key file for scraping metrics endpoint over HTTPs" .Values.clients.https.keyFile }} + - name: CACERT_FILE_NAME + value: {{ required "Need a TLS CA cert file for scraping metrics endpoint over HTTPs" .Values.clients.https.caCertFile }} + - name: CERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy.pem + - name: KEY_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-key.pem + - name: CACERT_FILE_TARGET + value: /etc/ssl/push-proxy/push-proxy-ca-cert.pem + securityContext: + runAsNonRoot: false +{{- if and .Values.global.seLinux.enabled .Values.clients.https.seLinuxOptions }} + seLinuxOptions: {{ .Values.clients.https.seLinuxOptions | toYaml | nindent 12 }} +{{- end }} + volumeMounts: + - name: metrics-cert-dir-source + mountPath: /etc/source + readOnly: true + - name: metrics-cert-dir + mountPath: /etc/ssl/push-proxy + volumes: + - name: metrics-cert-dir-source + hostPath: + path: {{ required "Need access to volume on host with the SSL cert files to use HTTPs" .Values.clients.https.certDir }} + - name: metrics-cert-dir + emptyDir: {} + {{- end }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml new file mode 100644 index 0000000000..eefe609058 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy-rbac.yaml @@ -0,0 +1,68 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +rules: +{{- if .Values.global.cattle.psp.enabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "pushProxy.proxy.name" . }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "pushProxy.proxy.name" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "pushProxy.proxy.name" . }} +subjects: + - kind: ServiceAccount + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +--- +{{- if .Values.global.cattle.psp.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ include "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + privileged: false + 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 + volumes: + - 'secret' +{{- end }}{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy.yaml new file mode 100644 index 0000000000..723bbd6c00 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-proxy.yaml @@ -0,0 +1,57 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if and .Values.proxy }}{{ if .Values.proxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} + pushprox-exporter: "proxy" +spec: + selector: + matchLabels: {{ include "pushProxy.proxy.labels" . | nindent 6 }} + template: + metadata: + labels: {{ include "pushProxy.proxy.labels" . | nindent 8 }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- if .Values.proxy.nodeSelector }} +{{ toYaml .Values.proxy.nodeSelector | indent 8 }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- if .Values.proxy.tolerations }} +{{ toYaml .Values.proxy.tolerations | indent 8 }} +{{- end }} + serviceAccountName: {{ template "pushProxy.proxy.name" . }} + {{- if .Values.global.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.global.imagePullSecretName }} + {{- end }} + containers: + - name: pushprox-proxy + image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }} + command: + {{- range .Values.proxy.command }} + - {{ . | quote }} + {{- end }} + {{- if .Values.proxy.resources }} + resources: {{ toYaml .Values.proxy.resources | nindent 10 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.proxy.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +spec: + ports: + - name: pp-proxy + port: {{ required "Need .Values.proxy.port to configure proxy" .Values.proxy.port }} + protocol: TCP + targetPort: {{ .Values.proxy.port }} + selector: {{ include "pushProxy.proxy.labels" . | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml new file mode 100644 index 0000000000..67eb2216b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/pushprox-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- template "applyKubeVersionOverrides" . -}} +{{- if .Values.serviceMonitor }}{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "pushprox.serviceMonitor.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.serviceMonitor.labels" . | nindent 4 }} +spec: + endpoints: {{include "pushProxy.serviceMonitor.endpoints" . | nindent 4 }} + jobLabel: component + podTargetLabels: + - component + - pushprox-exporter + namespaceSelector: + matchNames: + - {{ template "pushprox.namespace" . }} + selector: + matchLabels: {{ include "pushProxy.client.labels" . | nindent 6 }} +--- +{{- $selector := "" }} +{{- if not (kindIs "invalid" .Values.service) }} +{{- if not (kindIs "invalid" .Values.service.selector) }} +{{ if .Values.service.selector }} +{{- if .Values.clients.enabled }} +{{- required (printf "Cannot override .Values.service.selector=%s when .Values.clients.enabled=true" (toJson .Values.service.selector)) "" }} +{{- end }} +{{- $selector = (toYaml .Values.service.selector) }} +{{- end }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pushProxy.client.name" . }} + namespace: {{ template "pushprox.namespace" . }} + labels: {{ include "pushProxy.client.labels" . | nindent 4 }} +spec: + ports: + - name: metrics + port: {{ required "Need .Values.metricsPort to configure client to listen to metrics at port" .Values.metricsPort}} + protocol: TCP + targetPort: {{ .Values.metricsPort }} + selector: {{ default (include "pushProxy.client.labels" .) $selector | nindent 4 }} +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..16abc2fa83 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/validate-install-crd.yaml @@ -0,0 +1,14 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install Prometheus Operator CRDs before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..a30c59d3b7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/templates/validate-psp-install.yaml @@ -0,0 +1,7 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- if .Values.global.cattle.psp.enabled }} +#{{- if not (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +#{{- fail "The target cluster does not have the PodSecurityPolicy API resource. Please disable PSPs in this chart before proceeding." -}} +#{{- end }} +#{{- end }} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/values.yaml new file mode 100644 index 0000000000..1e076041b3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/rkeScheduler/values.yaml @@ -0,0 +1,166 @@ +# Default values for rancher-pushprox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Default image containing both the proxy and the client was generated from the following Dockerfile +# https://github.com/prometheus-community/PushProx/blob/eeadbe766641699129920ccfaaaa30a85c67fe81/Dockerfile#L1-L15 + +# Configuration + +global: + cattle: + psp: + enabled: false + systemDefaultRegistry: "" + seLinux: + enabled: false + +# A list of Semver constraint strings (defined by https://github.com/Masterminds/semver) and values.yaml overrides. +# +# For each key in kubeVersionOverrides, this chart will check to see if the current Kubernetes cluster's version matches +# any of the semver constraints provided as keys on the map. +# +# On seeing a match, the default value for each values.yaml field overridden will be updated with the new value. +# +# If multiple matches are encountered (due to overlapping semver ranges), the matches will be applied in order. +# +# Notes: +# - On running a helm template, Helm generally assumes the kubeVersion is v1.20.0 +# - On running a helm install --dry-run, the correct kubeVersion should be chosen. +kubeVersionOverrides: [] +# - constraint: "< 1.21" +# values: +# metricsPort: 10252 +# clients: +# https: +# enabled: false +# insecureSkipVerify: false +# useServiceAccountCredentials: false + +namespaceOverride: "" + +# The component that is being monitored (i.e. etcd) +component: "component" + +# The port containing the metrics that need to be scraped +metricsPort: 2739 + +# Configure ServiceMonitor that monitors metrics from the metricsPort endpoint +serviceMonitor: + enabled: true + # A list of endpoints that will be added to the ServiceMonitor based on the Endpoint spec + # Source: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#endpoint + # By default, proxyUrl and params._scheme will be overridden based on other values + endpoints: + - port: metrics + +# Configure Service that grabs scrape targets +service: + # The selector that is used to populate the Service's Endpoints object. + # The chart will error out on rendering templating if .Values.clients.enabled is set alongside this field, + # since it is expected that this service should point to the PushProx Clients Daemonset / Deployment + selector: {} + +clients: + enabled: true + # The port which the PushProx client will post PushProx metrics to + port: 9369 + # If unset, this will default to the URL for the proxy service: http://pushprox-{{component}}-proxy.{{namepsace}}.svc.cluster.local:{{proxy.port}} + # Should be modified if the clients are being deployed outside the cluster where the proxy rests, otherwise leave it null + proxyUrl: "" + # If set to true, the client will forward any requests from the host IP to 127.0.0.1 + # It will only allow proxy requests to the metricsPort specified + useLocalhost: false + # Configuration for accessing metrics via HTTPS + https: + # Does the client require https to access the metrics? + enabled: false + # Does the client require requests be sent to http or https? + forceHTTPSScheme: false + # If set to true, the client will create a service account with adequate permissions and set a flag + # on the client to use the service account token provided by it to make authorized scrape requests + useServiceAccountCredentials: false + # Configuration for authentication to metrics via https endpoint + authenticationMethod: + # Reads token from defined file in container + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenFile: + enabled: false + bearerTokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + # Reads token from defined secret in namespace + # This function is deprecated in the prometheus operator api and may be removed in a future version + bearerTokenSecret: + enabled: false + # Reads token from defined secret in namespace + authorization: + enabled: false + type: "bearer" + credentials: + key: "token" + optional: false + # If set to true, the client will disable SSL security checks + insecureSkipVerify: false + # Directory on host where necessary TLS cert and key to scrape metrics can be found + certDir: "" + # Filenames for files located in .Values.clients.https.certDir that correspond to TLS settings + certFile: "" + keyFile: "" + caCertFile: "" + # seLinuxOptions to be passed into the container that copies certs. Should define a container with permissions to read the files in the certDir provided on the host. + # Required and only used if `clients.https.enabled` is set and `clients.https.certDir` is provided. + seLinuxOptions: {} + + metrics: + # Whether the client should publish PushProx client-specific metrics to .Values.clients.port + enabled: false + + rbac: + # Additional permissions to provide to the ServiceAccount bound to the client + # This can be used to provide additional permissions for the client to scrape metrics from the k8s API + # Only enabled if clients.https.enabled and clients.https.useServiceAccountCredentials are true + additionalRules: [] + + # Resource limits + resources: {} + + # Options to select all nodes to deploy client DaemonSet on + nodeSelector: {} + tolerations: [] + affinity: {} + + image: + repository: rancher/pushprox-client + tag: v0.1.3-rancher2-client + command: ["pushprox-client"] + + copyCertsImage: + repository: rancher/mirrored-library-busybox + tag: 1.31.1 + + # The default intention of rancher-pushprox clients is to scrape hostNetwork metrics across all nodes. + # This can be used to scrape internal Kubernetes components or DaemonSets of hostNetwork Pods in + # situations where a cloud provider firewall prevents Pod-To-Host communication but not Pod-To-Pod. + # However, if the underlying hostNetwork Pod that is being scraped is managed by a Deployment, + # this advanced option enables users to deploy the client as a Deployment instead of a DaemonSet. + # If a user deploys this feature and the underlying Deployment's number of replicas changes, the user will + # be responsible for upgrading this chart accordingly to the right number of replicas. + deployment: + enabled: false + replicas: 0 + +proxy: + enabled: true + # The port through which PushProx clients will communicate to the proxy + port: 8080 + + # Resource limits + resources: {} + + # Options to select a node to run a single proxy deployment on + nodeSelector: {} + tolerations: [] + + image: + repository: rancher/pushprox-proxy + tag: v0.1.3-rancher2-proxy + command: ["pushprox-proxy"] diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/.helmignore b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/.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/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/Chart.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/Chart.yaml new file mode 100644 index 0000000000..784bb0ec7e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +appVersion: 0.25.1 +description: A Helm chart for prometheus windows-exporter +home: https://github.com/prometheus-community/windows_exporter/ +keywords: +- windows-exporter +- windows +- prometheus +- exporter +maintainers: +- email: github@jkroepke.de + name: jkroepke +name: windowsExporter +sources: +- https://github.com/prometheus-community/windows_exporter/ +type: application +version: 0.3.1 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/README.md b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/README.md new file mode 100644 index 0000000000..1da1c64e12 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/README.md @@ -0,0 +1,42 @@ +# Prometheus `Windows Exporter` + +Prometheus exporter for hardware and OS metrics exposed by Windows kernels, written in Go with pluggable metric collectors. + +This chart bootstraps a prometheus [`Windows Exporter`](http://github.com/prometheus-community/windows_exporter) daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Get Repository Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/prometheus-windows-exporter +``` + +_See [configuration](#configuring) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall 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._ + +## Configuring + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values prometheus-community/prometheus-windows-exporter +``` diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/scripts/configure-firewall.ps1 b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/scripts/configure-firewall.ps1 new file mode 100644 index 0000000000..9cbed7112d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/scripts/configure-firewall.ps1 @@ -0,0 +1,31 @@ +$ErrorActionPreference = 'Continue' + +function CheckFirewallRuleError { + # We hit an error. This can happen for a number of reasons, including if the rule already exists + if ($error[0]) { + if (($error[0].Exception.NativeErrorCode) -and ($error[0].Exception.NativeErrorCode.ToString() -eq "AlreadyExists")) { + # Previous versions of monitoring may have already created this Firewall Rule + # Because of this, if the rule alreadys exists there is no need to delete and recreate it. + Write-Host "Detected Existing Firewall Rule, Nothing To Do" + } else { + Write-Host "Error Encountered Setting Up Required Firewall Rule" + $error[0].Exception + exit 1 + } + } +} + +Write-Host "Attempting To Configure Firewall Rules For Ports 9796, 10250" + +# This is the exact same firewall rule that has historically been created by rancher-wins +# https://github.com/rancher/wins/blob/91f670c47f19c6d9fe97d8f66a695d3081ad994f/pkg/apis/process_service_mgmt.go#L149 +New-NetFirewallRule -DisplayName rancher-wins-windows-exporter-TCP-9796 -Name rancher-wins-windows-exporter-TCP-9796 -Action Allow -Protocol TCP -LocalPort 9796 -Enabled True -PolicyStore ActiveStore +CheckFirewallRuleError +Write-Host "Windows Node Exporter Firewall Rule Successfully Created" + +# This rule is required in order to have the Rancher UI display node metrics in the 'Nodes' tab of the cluster explorer +New-NetFirewallRule -DisplayName rancher-wins-windows-exporter-TCP-10250 -Name rancher-wins-windows-exporter-TCP-10250 -Action Allow -Protocol TCP -LocalPort 10250 -Enabled True -PolicyStore ActiveStore +CheckFirewallRuleError +Write-Host "Windows Prometheus Metrics Firewall Rule Successfully Created" + +Write-Host "All Firewall Rules Successfully Configured" diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/_helpers.tpl new file mode 100644 index 0000000000..c9a5d6db8c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/_helpers.tpl @@ -0,0 +1,216 @@ +{{/* +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. +The components in this chart create additional resources that expand the longest created name strings. +The longest name that gets created adds and extra 37 characters, so truncation should be 63-35=26. +*/}} +{{- define "prometheus-windows-exporter.fullname" -}} +{{ printf "%s-windows-exporter" .Release.Name }} +{{- end -}} + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +{{- define "windowsExporter.renamedMetricsRelabeling" -}} +{{- range $original, $new := (include "windowsExporter.renamedMetrics" . | fromJson) -}} +- sourceLabels: [__name__] + regex: {{ $original }} + replacement: '{{ $new }}' + targetLabel: __name__ +{{ end -}} +{{- end -}} + +{{- define "windowsExporter.labels" -}} +k8s-app: {{ template "prometheus-windows-exporter.fullname" . }} +release: {{ .Release.Name }} +component: "windows-exporter" +provider: kubernetes +{{- end -}} + +{{- define "windowsExporter.renamedMetrics" -}} +{{- $renamed := dict -}} +{{/* v0.15.0 */}} +{{- $_ := set $renamed "windows_mssql_transactions_active_total" "windows_mssql_transactions_active" -}} +{{/* v0.16.0 */}} +{{- $_ := set $renamed "windows_adfs_ad_login_connection_failures" "windows_adfs_ad_login_connection_failures_total" -}} +{{- $_ := set $renamed "windows_adfs_certificate_authentications" "windows_adfs_certificate_authentications_total" -}} +{{- $_ := set $renamed "windows_adfs_device_authentications" "windows_adfs_device_authentications_total" -}} +{{- $_ := set $renamed "windows_adfs_extranet_account_lockouts" "windows_adfs_extranet_account_lockouts_total" -}} +{{- $_ := set $renamed "windows_adfs_federated_authentications" "windows_adfs_federated_authentications_total" -}} +{{- $_ := set $renamed "windows_adfs_passport_authentications" "windows_adfs_passport_authentications_total" -}} +{{- $_ := set $renamed "windows_adfs_password_change_failed" "windows_adfs_password_change_failed_total" -}} +{{- $_ := set $renamed "windows_adfs_password_change_succeeded" "windows_adfs_password_change_succeeded_total" -}} +{{- $_ := set $renamed "windows_adfs_token_requests" "windows_adfs_token_requests_total" -}} +{{- $_ := set $renamed "windows_adfs_windows_integrated_authentications" "windows_adfs_windows_integrated_authentications_total" -}} +{{- $_ := set $renamed "windows_net_packets_outbound_errors" "windows_net_packets_outbound_errors_total" -}} +{{- $_ := set $renamed "windows_net_packets_received_discarded" "windows_net_packets_received_discarded_total" -}} +{{- $_ := set $renamed "windows_net_packets_received_errors" "windows_net_packets_received_errors_total" -}} +{{- $_ := set $renamed "windows_net_packets_received_total" "windows_net_packets_received_total_total" -}} +{{- $_ := set $renamed "windows_net_packets_received_unknown" "windows_net_packets_received_unknown_total" -}} +{{- $_ := set $renamed "windows_dns_memory_used_bytes_total" "windows_dns_memory_used_bytes" -}} +{{- $renamed | toJson -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "prometheus-windows-exporter.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "prometheus-windows-exporter.labels" -}} +helm.sh/chart: {{ include "prometheus-windows-exporter.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: metrics +app.kubernetes.io/part-of: {{ include "prometheus-windows-exporter.name" . }} +{{ include "prometheus-windows-exporter.selectorLabels" . }} +{{- with .Chart.AppVersion }} +app.kubernetes.io/version: {{ . | quote }} +{{- end }} +{{- with .Values.podLabels }} +{{ toYaml . }} +{{- end }} +{{- if .Values.releaseLabel }} +release: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "prometheus-windows-exporter.selectorLabels" -}} +app.kubernetes.io/name: {{ include "prometheus-windows-exporter.fullname" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "prometheus-windows-exporter.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "prometheus-windows-exporter.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +The image to use +*/}} +{{- define "prometheus-windows-exporter.image" -}} +{{- if .Values.image.sha }} +{{- fail "image.sha forbidden. Use image.digest instead" }} +{{- else if .Values.image.digest }} +{{- if .Values.global.cattle.systemDefaultRegistry }} +{{- printf "%s/%s:%s@%s" .Values.global.cattle.systemDefaultRegistry .Values.image.repository (default .Chart.AppVersion .Values.image.tag) .Values.image.digest }} +{{- else }} +{{- printf "%s/%s:%s@%s" .Values.image.registry .Values.image.repository (default .Chart.AppVersion .Values.image.tag) .Values.image.digest }} +{{- end }} +{{- else }} +{{- if .Values.global.cattle.systemDefaultRegistry }} +{{- printf "%s/%s:%s" .Values.global.cattle.systemDefaultRegistry .Values.image.repository (default .Chart.AppVersion .Values.image.tag) }} +{{- else }} +{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (default .Chart.AppVersion .Values.image.tag) }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "prometheus-windows-exporter.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Create the namespace name of the service monitor +*/}} +{{- define "prometheus-windows-exporter.monitor-namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- if .Values.prometheus.monitor.namespace }} +{{- .Values.prometheus.monitor.namespace }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for servicemonitor */}} +{{- define "servicemonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end }} + +{{/* +Formats imagePullSecrets. Input is (dict "Values" .Values "imagePullSecrets" .{specific imagePullSecrets}) +*/}} +{{- define "prometheus-windows-exporter.imagePullSecrets" -}} +{{- range (concat .Values.global.imagePullSecrets .imagePullSecrets) }} + {{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml . | trim }} + {{- else }} +- name: {{ . }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +Create the namespace name of the pod monitor +*/}} +{{- define "prometheus-windows-exporter.podmonitor-namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- if .Values.prometheus.podMonitor.namespace }} +{{- .Values.prometheus.podMonitor.namespace }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Sets default scrape limits for podmonitor */}} +{{- define "podmonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/config.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/config.yaml new file mode 100644 index 0000000000..25f1fa69c2 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/config.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "prometheus-windows-exporter.fullname" . }} + namespace: {{ include "prometheus-windows-exporter.namespace" . }} + labels: + {{- include "windowsExporter.labels" $ | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + config.yml: | + {{- .Values.config | nindent 4 }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/daemonset.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/daemonset.yaml new file mode 100644 index 0000000000..be7feb3ed1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/daemonset.yaml @@ -0,0 +1,200 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "prometheus-windows-exporter.fullname" . }} + namespace: {{ include "prometheus-windows-exporter.namespace" . }} + labels: + {{- include "windowsExporter.labels" . | nindent 4 }} + {{- with .Values.daemonsetAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "windowsExporter.labels" . | nindent 6 }} + {{- with .Values.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "windowsExporter.labels" . | nindent 8 }} + spec: + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + initContainers: + - name: configure-firewall + image: {{ include "prometheus-windows-exporter.image" . }} + command: + - C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe + args: ["-f", "scripts/configure-firewall.ps1"] + volumeMounts: + - mountPath: /scripts + name: exporter-scripts + {{- with .Values.extraInitContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "prometheus-windows-exporter.fullname" . }} + containers: + - name: windows-exporter + image: {{ include "prometheus-windows-exporter.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - --config.file=%CONTAINER_SANDBOX_MOUNT_POINT%/config.yml + - --collector.textfile.directories=%CONTAINER_SANDBOX_MOUNT_POINT% + - --web.listen-address=:{{ .Values.service.port }} + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + hostPort: {{ .Values.service.port }} + protocol: TCP + livenessProbe: + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + httpGet: + httpHeaders: + {{- range $_, $header := .Values.livenessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: / + port: {{ .Values.service.port }} + scheme: {{ upper .Values.livenessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + readinessProbe: + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + httpHeaders: + {{- range $_, $header := .Values.readinessProbe.httpGet.httpHeaders }} + - name: {{ $header.name }} + value: {{ $header.value }} + {{- end }} + path: / + port: {{ .Values.service.port }} + scheme: {{ upper .Values.readinessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config.yml + subPath: config.yml + {{- range $_, $mount := .Values.extraHostVolumeMounts }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} + {{- end }} + {{- range $_, $mount := .Values.sidecarVolumeMount }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: true + {{- end }} + {{- range $_, $mount := .Values.configmaps }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + {{- end }} + {{- range $_, $mount := .Values.secrets }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + {{- with .Values.sidecars }} + {{- toYaml . | nindent 8 }} + {{- if or .Values.sidecarVolumeMount .Values.sidecarHostVolumeMounts }} + volumeMounts: + {{- range $_, $mount := .Values.sidecarVolumeMount }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} + {{- end }} + {{- range $_, $mount := .Values.sidecarHostVolumeMounts }} + - name: {{ $mount.name }} + mountPath: {{ $mount.mountPath }} + readOnly: {{ $mount.readOnly }} + {{- end }} + {{- end }} + {{- end }} + {{- if or .Values.imagePullSecrets .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "prometheus-windows-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.imagePullSecrets) | indent 8 }} + {{- end }} + hostNetwork: {{ .Values.hostNetwork }} + hostPID: {{ .Values.hostPID }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: exporter-scripts + configMap: + name: {{ include "prometheus-windows-exporter.fullname" . }}-scripts + - name: config + configMap: + name: {{ include "prometheus-windows-exporter.fullname" . }} + {{- range $_, $mount := .Values.extraHostVolumeMounts }} + - name: {{ $mount.name }} + hostPath: + path: {{ $mount.hostPath }} + {{- end }} + {{- range $_, $mount := .Values.sidecarVolumeMount }} + - name: {{ $mount.name }} + emptyDir: + medium: Memory + {{- end }} + {{- range $_, $mount := .Values.sidecarHostVolumeMounts }} + - name: {{ $mount.name }} + hostPath: + path: {{ $mount.hostPath }} + {{- end }} + {{- range $_, $mount := .Values.configmaps }} + - name: {{ $mount.name }} + configMap: + name: {{ $mount.name }} + {{- end }} + {{- range $_, $mount := .Values.secrets }} + - name: {{ $mount.name }} + secret: + secretName: {{ $mount.name }} + {{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/podmonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/podmonitor.yaml new file mode 100644 index 0000000000..bbb6c39340 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/podmonitor.yaml @@ -0,0 +1,91 @@ +{{- if .Values.prometheus.podMonitor.enabled }} +apiVersion: {{ .Values.prometheus.podMonitor.apiVersion | default "monitoring.coreos.com/v1" }} +kind: PodMonitor +metadata: + name: {{ include "prometheus-windows-exporter.fullname" . }} + namespace: {{ include "prometheus-windows-exporter.podmonitor-namespace" . }} + labels: + {{- include "windowsExporter.labels" . | nindent 4 }} + {{- with .Values.prometheus.podMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.podMonitor.jobLabel }} + {{- include "podmonitor.scrapeLimits" .Values.prometheus.podMonitor | nindent 2 }} + selector: + matchLabels: + {{- with .Values.prometheus.podMonitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "prometheus-windows-exporter.selectorLabels" . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "prometheus-windows-exporter.namespace" . }} + {{- with .Values.prometheus.podMonitor.attachMetadata }} + attachMetadata: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} + podMetricsEndpoints: + - port: {{ .Values.service.portName }} + {{- with .Values.prometheus.podMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.path }} + path: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.basicAuth }} + basicAuth: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.bearerTokenSecret }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.authorization }} + authorization: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.oauth2 }} + oauth2: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.proxyUrl }} + proxyUrl: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.honorTimestamps }} + honorTimestamps: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.honorLabels }} + honorLabels: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.prometheus.podMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.podMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + enableHttp2: {{ default false .Values.prometheus.podMonitor.enableHttp2 }} + filterRunning: {{ default true .Values.prometheus.podMonitor.filterRunning }} + followRedirects: {{ default false .Values.prometheus.podMonitor.followRedirects }} + {{- with .Values.prometheus.podMonitor.params }} + params: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/scriptConfig.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/scriptConfig.yaml new file mode 100644 index 0000000000..f514c8161a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/scriptConfig.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "prometheus-windows-exporter.fullname" . }}-scripts + namespace: {{ include "prometheus-windows-exporter.namespace" . }} + labels: + {{- include "windowsExporter.labels" $ | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: +{{ (.Files.Glob "scripts/*").AsConfig | indent 2 }} + diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/service.yaml new file mode 100644 index 0000000000..267b796f63 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/service.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "prometheus-windows-exporter.fullname" . }} + namespace: {{ include "prometheus-windows-exporter.namespace" . }} + labels: + {{- include "windowsExporter.labels" $ | nindent 4 }} + {{- if or .Values.prometheus.monitor.enabled .Values.prometheus.podMonitor.enabled }} + {{- with .Values.service.annotations }} + annotations: + {{- unset . "prometheus.io/scrape" | toYaml | nindent 4 }} + {{- end }} + {{- else }} + annotations: + prometheus.io/scrape: "true" + {{- with .Values.service.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + {{- if ( and (eq .Values.service.type "NodePort" ) (not (empty .Values.service.nodePort)) ) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + targetPort: {{ .Values.service.port }} + protocol: TCP + appProtocol: http + name: {{ .Values.service.portName }} + selector: + {{- include "windowsExporter.labels" . | nindent 4 }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/serviceaccount.yaml new file mode 100644 index 0000000000..14c1c46807 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.rbac.create .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "prometheus-windows-exporter.serviceAccountName" . }} + namespace: {{ include "prometheus-windows-exporter.namespace" . }} + labels: + {{- include "windowsExporter.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if or .Values.serviceAccount.imagePullSecrets .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- include "prometheus-windows-exporter.imagePullSecrets" (dict "Values" .Values "imagePullSecrets" .Values.serviceAccount.imagePullSecrets) | indent 2 }} +{{- end }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/servicemonitor.yaml new file mode 100644 index 0000000000..2effc07758 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/templates/servicemonitor.yaml @@ -0,0 +1,75 @@ +{{- if .Values.prometheus.monitor.enabled }} +apiVersion: {{ .Values.prometheus.monitor.apiVersion | default "monitoring.coreos.com/v1" }} +kind: ServiceMonitor +metadata: + name: {{ include "prometheus-windows-exporter.fullname" . }} + namespace: {{ include "prometheus-windows-exporter.monitor-namespace" . }} + labels: + {{- include "windowsExporter.labels" . | nindent 4 }} + {{- with .Values.prometheus.monitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.prometheus.monitor | nindent 2 }} + {{- with .Values.prometheus.monitor.podTargetLabels }} + podTargetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- with .Values.prometheus.monitor.selectorOverride }} + {{- toYaml . | nindent 6 }} + {{- else }} + {{- include "windowsExporter.labels" . | nindent 6 }} + {{- end }} + {{- with .Values.prometheus.monitor.attachMetadata }} + attachMetadata: + {{- toYaml . | nindent 4 }} + {{- end }} + endpoints: + - port: {{ .Values.service.portName }} + scheme: {{ .Values.prometheus.monitor.scheme }} + {{- with .Values.prometheus.monitor.basicAuth }} + basicAuth: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.monitor.bearerTokenFile }} + bearerTokenFile: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + metricRelabelings: +{{- include "windowsExporter.renamedMetricsRelabeling" . | nindent 6 -}} + - sourceLabels: [__name__] + regex: 'wmi_(.*)' + replacement: 'windows_$1' + targetLabel: __name__ + - sourceLabels: [volume, nic] + regex: (.*);(.*) + separator: '' + targetLabel: device + action: replace + replacement: $1$2 + - sourceLabels: [__name__] + regex: windows_cs_logical_processors + replacement: 'system' + targetLabel: mode + relabelings: + - separator: ':' + sourceLabels: + - __meta_kubernetes_pod_host_ip + - __meta_kubernetes_pod_container_port_number + targetLabel: instance +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/values.yaml new file mode 100644 index 0000000000..04569505d6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/charts/windowsExporter/values.yaml @@ -0,0 +1,366 @@ +# Default values for prometheus-windows-exporter. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +image: + registry: docker.io + repository: rancher/mirrored-prometheus-windows-exporter + # Overrides the image tag whose default is {{ printf "v%s" .Chart.AppVersion }} + tag: "0.25.1" + pullPolicy: IfNotPresent + digest: "" + +config: |- + collectors: + enabled: '[defaults],tcp,memory,container' + +imagePullSecrets: [] +# - name: "image-pull-secret" +nameOverride: "" +fullnameOverride: "" + +global: + # To help compatibility with other charts which use global.imagePullSecrets. + # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). + # global: + # imagePullSecrets: + # - name: pullSecret1 + # - name: pullSecret2 + # or + # global: + # imagePullSecrets: + # - pullSecret1 + # - pullSecret2 + imagePullSecrets: [] + cattle: + systemDefaultRegistry: "" + +service: + type: ClusterIP + port: 9796 + nodePort: + portName: windows-metrics + annotations: {} + +# Additional environment variables that will be passed to the daemonset +env: {} +## env: +## VARIABLE: value + +prometheus: + monitor: + enabled: true + additionalLabels: {} + namespace: "" + + jobLabel: "component" + + # List of pod labels to add to windows exporter metrics + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor + podTargetLabels: ["component"] + + scheme: http + basicAuth: {} + bearerTokenFile: + tlsConfig: {} + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## Override serviceMonitor selector + ## + selectorOverride: {} + + ## Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. + ## + attachMetadata: + node: false + + relabelings: [] + metricRelabelings: [] + interval: "" + scrapeTimeout: 10s + ## prometheus.monitor.apiVersion ApiVersion for the serviceMonitor Resource(defaults to "monitoring.coreos.com/v1") + apiVersion: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + # PodMonitor defines monitoring for a set of pods. + # ref. https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor + # Using a PodMonitor may be preferred in some environments where there is very large number + # of Windows Exporter endpoints (1000+) behind a single service. + # The PodMonitor is disabled by default. When switching from ServiceMonitor to PodMonitor, + # the time series resulting from the configuration through PodMonitor may have different labels. + # For instance, there will not be the service label any longer which might + # affect PromQL queries selecting that label. + podMonitor: + enabled: false + # Namespace in which to deploy the pod monitor. Defaults to the release namespace. + namespace: "" + # Additional labels, e.g. setting a label for pod monitor selector as set in prometheus + additionalLabels: {} + # release: kube-prometheus-stack + # PodTargetLabels transfers labels of the Kubernetes Pod onto the target. + podTargetLabels: [] + # apiVersion defaults to monitoring.coreos.com/v1. + apiVersion: "" + # Override pod selector to select pod objects. + selectorOverride: {} + # Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above. + attachMetadata: + node: false + # The label to use to retrieve the job name from. Defaults to label app.kubernetes.io/name. + jobLabel: "" + + # Scheme/protocol to use for scraping. + scheme: "http" + # Path to scrape metrics at. + path: "/metrics" + + # BasicAuth allow an endpoint to authenticate over basic authentication. + # More info: https://prometheus.io/docs/operating/configuration/#endpoint + basicAuth: {} + # Secret to mount to read bearer token for scraping targets. + # The secret needs to be in the same namespace as the pod monitor and accessible by the Prometheus Operator. + # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secretkeyselector-v1-core + bearerTokenSecret: {} + # TLS configuration to use when scraping the endpoint. + tlsConfig: {} + # Authorization section for this endpoint. + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.SafeAuthorization + authorization: {} + # OAuth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer. + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.OAuth2 + oauth2: {} + + # ProxyURL eg http://proxyserver:2195. Directs scrapes through proxy to this endpoint. + proxyUrl: "" + # Interval at which endpoints should be scraped. If not specified Prometheus’ global scrape interval is used. + interval: "" + # Timeout after which the scrape is ended. If not specified, the Prometheus global scrape interval is used. + scrapeTimeout: "" + # HonorTimestamps controls whether Prometheus respects the timestamps present in scraped data. + honorTimestamps: true + # HonorLabels chooses the metric’s labels on collisions with target labels. + honorLabels: true + # Whether to enable HTTP2. Default false. + enableHttp2: "" + # Drop pods that are not running. (Failed, Succeeded). + # Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase + filterRunning: "" + # FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. Default false. + followRedirects: "" + # Optional HTTP URL parameters + params: {} + + # RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds + # relabelings for a few standard Kubernetes fields. The original scrape job’s name + # is available via the __tmp_prometheus_job_name label. + # More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + relabelings: [] + # MetricRelabelConfigs to apply to samples before ingestion. + metricRelabelings: [] + + # SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + sampleLimit: 0 + # TargetLimit defines a limit on the number of scraped targets that will be accepted. + targetLimit: 0 + # Per-scrape limit on number of labels that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelLimit: 0 + # Per-scrape limit on length of labels name that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelNameLengthLimit: 0 + # Per-scrape limit on length of labels value that will be accepted for a sample. + # Only valid in Prometheus versions 2.27.0 and newer. + labelValueLengthLimit: 0 + +## Customize the updateStrategy if set +updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + +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: 200m + # memory: 50Mi + # requests: + # cpu: 100m +# memory: 30Mi + +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: {} + imagePullSecrets: [] + automountServiceAccountToken: false + +securityContext: + windowsOptions: + hostProcess: true + runAsUserName: "NT AUTHORITY\\system" + +rbac: + ## If true, create & use RBAC resources + ## + create: true + +# Expose the service to the host network +hostNetwork: true + +# Share the host process ID namespace +hostPID: true + +## Assign a group of affinity scheduling rules +## +affinity: {} +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchFields: +# - key: metadata.name +# operator: In +# values: +# - target-host-name + +# Annotations to be added to windows exporter pods +podAnnotations: + # Fix for very slow GKE cluster upgrades + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + +# Extra labels to be added to windows exporter pods +podLabels: {} + +# Annotations to be added to windows exporter daemonset +daemonsetAnnotations: {} + +## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box +releaseLabel: false + +# Custom DNS configuration to be added to prometheus-windows-exporter pods +dnsConfig: {} +# nameservers: +# - 1.2.3.4 +# searches: +# - ns1.svc.cluster-domain.example +# - my.dns.search.suffix +# options: +# - name: ndots +# value: "2" +# - name: edns0 + +## Assign a nodeSelector if operating a hybrid cluster +## +nodeSelector: + kubernetes.io/os: windows + # kubernetes.io/arch: amd64 + +tolerations: + - effect: NoSchedule + operator: Exists + +## Assign a PriorityClassName to pods if set +# priorityClassName: "" + +## Additional container arguments +## +extraArgs: [] +# - --collector.service.services-where +# - "Name LIKE 'sql%'" + +## Additional mounts from the host to windows-exporter container +## +extraHostVolumeMounts: [] +# - name: +# hostPath: +# mountPath: +# readOnly: true|false + +## Additional configmaps to be mounted. +## +configmaps: [] +# - name: +# mountPath: +secrets: [] +# - name: +# mountPath: +## Override the deployment namespace +## +namespaceOverride: "" + +## Additional containers for export metrics to text file +## +sidecars: [] +## - name: nvidia-dcgm-exporter +## image: nvidia/dcgm-exporter:1.4.3 + +## Volume for sidecar containers +## +sidecarVolumeMount: [] +## - name: collector-textfiles +## mountPath: /run/prometheus +## readOnly: false + +## Additional mounts from the host to sidecar containers +## +sidecarHostVolumeMounts: [] +# - name: +# hostPath: +# mountPath: +# readOnly: true|false +# mountPropagation: None|HostToContainer|Bidirectional + +## Additional InitContainers to initialize the pod +## +extraInitContainers: [] + +## Liveness probe +## +livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + +## Readiness probe +## +readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: [] + scheme: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/ingress-nginx/nginx.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/ingress-nginx/nginx.json new file mode 100644 index 0000000000..565352235a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/ingress-nginx/nginx.json @@ -0,0 +1,1445 @@ +{ + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + }, + { + "datasource": "$datasource", + "enable": true, + "expr": "sum(changes(nginx_ingress_controller_config_last_reload_successful_timestamp_seconds{instance!=\"unknown\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[30s])) by (controller_class)", + "hide": false, + "iconColor": "rgba(255, 96, 96, 1)", + "limit": 100, + "name": "Config Reloads", + "showIn": 0, + "step": "30s", + "tagKeys": "controller_class", + "tags": [], + "titleFormat": "Config Reloaded", + "type": "tags" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1534359654832, + "links": [], + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "$datasource", + "format": "ops", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 20, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "round(sum(irate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[2m])), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Controller Request Volume", + "transparent": false, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "$datasource", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 82, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(avg_over_time(nginx_ingress_controller_nginx_process_connections{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",state=\"active\"}[2m]))", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Controller Connections", + "transparent": false, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "$datasource", + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 80, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": false + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 21, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",status!~\"[4-5].*\"}[2m])) / sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[2m]))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "95, 99, 99.5", + "title": "Controller Success Rate (non-4|5xx responses)", + "transparent": false, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "$datasource", + "decimals": 0, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 18, + "y": 0 + }, + "id": 81, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "avg(irate(nginx_ingress_controller_success{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[1m])) * 60", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Config Reloads", + "transparent": false, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "total" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "$datasource", + "decimals": 0, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 0 + }, + "id": 83, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "count(nginx_ingress_controller_config_last_reload_successful{controller_pod=~\"$controller\",controller_namespace=~\"$namespace\"} == 0)", + "format": "time_series", + "instant": true, + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Last Config Failed", + "transparent": false, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 3 + }, + "height": "200px", + "id": 86, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": false, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "h", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress), 0.001)", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ ingress }}", + "metric": "network", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Ingress Request Volume", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "transparent": false, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "max - istio-proxy": "#890f02", + "max - master": "#bf1b00", + "max - prometheus": "#bf1b00" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": 2, + "editable": false, + "error": false, + "fill": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 3 + }, + "id": 87, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 300, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",ingress=~\"$ingress\",status!~\"[4-5].*\"}[2m])) by (ingress) / sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", + "format": "time_series", + "instant": false, + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "{{ ingress }}", + "metric": "container_memory_usage:sort_desc", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Ingress Success Rate (non-4|5xx responses)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 1, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "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 + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 10 + }, + "height": "200px", + "id": 32, + "isNew": true, + "legend": { + "alignAsTable": false, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (irate (nginx_ingress_controller_request_size_sum{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m]))", + "format": "time_series", + "instant": false, + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "Received", + "metric": "network", + "refId": "A", + "step": 10 + }, + { + "expr": "- sum (irate (nginx_ingress_controller_response_size_sum{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m]))", + "format": "time_series", + "hide": false, + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "Sent", + "metric": "network", + "refId": "B", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Network I/O pressure", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "transparent": false, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "max - istio-proxy": "#890f02", + "max - master": "#bf1b00", + "max - prometheus": "#bf1b00" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": 2, + "editable": false, + "error": false, + "fill": 0, + "grid": {}, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 10 + }, + "id": 77, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(nginx_ingress_controller_nginx_process_resident_memory_bytes{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}) ", + "format": "time_series", + "instant": false, + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "nginx", + "metric": "container_memory_usage:sort_desc", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Average Memory Usage", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "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": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "max - istio-proxy": "#890f02", + "max - master": "#bf1b00" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": 3, + "editable": false, + "error": false, + "fill": 0, + "grid": {}, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 10 + }, + "height": "", + "id": 79, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sort": null, + "sortDesc": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg (rate (nginx_ingress_controller_nginx_process_cpu_seconds_total{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m])) ", + "format": "time_series", + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "nginx", + "metric": "container_cpu", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + { + "colorMode": "critical", + "fill": true, + "line": true, + "op": "gt" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Average CPU Usage", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "transparent": false, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "cores", + "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": 24, + "x": 0, + "y": 16 + }, + "hideTimeOverride": false, + "id": 75, + "links": [], + "pageSize": 7, + "repeat": null, + "repeatDirection": "h", + "scroll": true, + "showHeader": true, + "sort": { + "col": 1, + "desc": true + }, + "styles": [ + { + "alias": "Ingress", + "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, + "pattern": "ingress", + "preserveFormat": false, + "sanitize": false, + "thresholds": [], + "type": "string", + "unit": "short" + }, + { + "alias": "Requests", + "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, + "pattern": "Value #A", + "thresholds": [ + "" + ], + "type": "number", + "unit": "ops" + }, + { + "alias": "Errors", + "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, + "pattern": "Value #B", + "thresholds": [], + "type": "number", + "unit": "ops" + }, + { + "alias": "P50 Latency", + "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": 0, + "link": false, + "pattern": "Value #C", + "thresholds": [], + "type": "number", + "unit": "dtdurations" + }, + { + "alias": "P90 Latency", + "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": 0, + "pattern": "Value #D", + "thresholds": [], + "type": "number", + "unit": "dtdurations" + }, + { + "alias": "P99 Latency", + "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": 0, + "pattern": "Value #E", + "thresholds": [], + "type": "number", + "unit": "dtdurations" + }, + { + "alias": "IN", + "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, + "pattern": "Value #F", + "thresholds": [ + "" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "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, + "pattern": "Time", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "OUT", + "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": "Value #G", + "thresholds": [], + "type": "number", + "unit": "Bps" + } + ], + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ ingress }}", + "refId": "C" + }, + { + "expr": "histogram_quantile(0.90, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ ingress }}", + "refId": "D" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }}", + "refId": "E" + }, + { + "expr": "sum(irate(nginx_ingress_controller_request_size_sum{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", + "format": "table", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ ingress }}", + "refId": "F" + }, + { + "expr": "sum(irate(nginx_ingress_controller_response_size_sum{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", + "format": "table", + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ ingress }}", + "refId": "G" + } + ], + "timeFrom": null, + "title": "Ingress Percentile Response Times and Transfer Rates", + "transform": "table", + "transparent": false, + "type": "table" + }, + { + "columns": [ + { + "text": "Current", + "value": "current" + } + ], + "datasource": "$datasource", + "fontSize": "100%", + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 24 + }, + "height": "1024", + "id": 85, + "links": [], + "pageSize": 7, + "scroll": true, + "showHeader": true, + "sort": { + "col": 1, + "desc": false + }, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "TTL", + "colorMode": "cell", + "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": 0, + "pattern": "Current", + "thresholds": [ + "0", + "691200" + ], + "type": "number", + "unit": "s" + }, + { + "alias": "", + "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": "avg(nginx_ingress_controller_ssl_expire_time_seconds{kubernetes_pod_name=~\"$controller\",namespace=~\"$namespace\",ingress=~\"$ingress\"}) by (host) - time()", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ host }}", + "metric": "gke_letsencrypt_cert_expiration", + "refId": "A", + "step": 1 + } + ], + "title": "Ingress Certificate Expiry", + "transform": "timeseries_aggregations", + "type": "table" + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "nginx" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": ".*", + "current": { + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": "Namespace", + "multi": false, + "name": "namespace", + "options": [], + "query": "label_values(nginx_ingress_controller_config_hash, controller_namespace)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".*", + "current": { + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": "Controller Class", + "multi": false, + "name": "controller_class", + "options": [], + "query": "label_values(nginx_ingress_controller_config_hash{namespace=~\"$namespace\"}, controller_class) ", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".*", + "current": { + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": "Controller", + "multi": false, + "name": "controller", + "options": [], + "query": "label_values(nginx_ingress_controller_config_hash{namespace=~\"$namespace\",controller_class=~\"$controller_class\"}, controller_pod) ", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".*", + "current": { + "tags": [], + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": "Ingress", + "multi": false, + "name": "ingress", + "options": [], + "query": "label_values(nginx_ingress_controller_requests{namespace=~\"$namespace\",controller_class=~\"$controller_class\",controller_pod=~\"$controller\"}, ingress) ", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "2m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "NGINX / Ingress Controller", + "uid": "nginx", + "version": 1 +} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/ingress-nginx/request-handling-performance.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/ingress-nginx/request-handling-performance.json new file mode 100644 index 0000000000..156e33123d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/ingress-nginx/request-handling-performance.json @@ -0,0 +1,963 @@ +{ + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "gnetId": 9614, + "graphTooltip": 1, + "id": null, + "iteration": 1582146566338, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Total time taken for nginx and upstream servers to process a request and send a response", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 91, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "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": "histogram_quantile(\n 0.5,\n sum by (le)(\n rate(\n nginx_ingress_controller_request_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", + "interval": "", + "legendFormat": ".5", + "refId": "D" + }, + { + "expr": "histogram_quantile(\n 0.95,\n sum by (le)(\n rate(\n nginx_ingress_controller_request_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", + "interval": "", + "legendFormat": ".95", + "refId": "B" + }, + { + "expr": "histogram_quantile(\n 0.99,\n sum by (le)(\n rate(\n nginx_ingress_controller_request_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", + "interval": "", + "legendFormat": ".99", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total request handling time", + "tooltip": { + "shared": true, + "sort": 0, + "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": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "The time spent on receiving the response from the upstream server", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "hiddenSeries": false, + "id": 94, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "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": "histogram_quantile(\n 0.5,\n sum by (le)(\n rate(\n nginx_ingress_controller_response_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": ".5", + "refId": "D" + }, + { + "expr": "histogram_quantile(\n 0.95,\n sum by (le)(\n rate(\n nginx_ingress_controller_response_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", + "interval": "", + "legendFormat": ".95", + "refId": "B" + }, + { + "expr": "histogram_quantile(\n 0.99,\n sum by (le)(\n rate(\n nginx_ingress_controller_response_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", + "interval": "", + "legendFormat": ".99", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Upstream response time", + "tooltip": { + "shared": true, + "sort": 0, + "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": 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": 0, + "y": 8 + }, + "hiddenSeries": false, + "id": 93, + "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": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": " sum by (path)(\n rate(\n nginx_ingress_controller_request_duration_seconds_count{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ path }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Request volume by Path", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "reqps", + "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", + "description": "For each path observed, its median upstream response time", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "hiddenSeries": false, + "id": 98, + "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": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(\n .5,\n sum by (le, path)(\n rate(\n nginx_ingress_controller_response_duration_seconds_bucket{\n ingress =~ \"$ingress\"\n }[1m]\n )\n )\n)", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ path }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Median upstream response time by Path", + "tooltip": { + "shared": true, + "sort": 0, + "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": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Percentage of 4xx and 5xx responses among all responses.", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 100, + "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 as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (path) (rate(nginx_ingress_controller_request_duration_seconds_count{\n ingress =~ \"$ingress\",\n status =~ \"[4-5].*\"\n}[1m])) / sum by (path) (rate(nginx_ingress_controller_request_duration_seconds_count{\n ingress =~ \"$ingress\",\n}[1m]))", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ path }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Response error rate by Path", + "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": 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", + "description": "For each path observed, the sum of upstream request time", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 16 + }, + "hiddenSeries": false, + "id": 102, + "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": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (path) (rate(nginx_ingress_controller_response_duration_seconds_sum{ingress =~ \"$ingress\"}[1m]))", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ path }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Upstream time consumed by Path", + "tooltip": { + "shared": true, + "sort": 0, + "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": 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": 0, + "y": 24 + }, + "hiddenSeries": false, + "id": 101, + "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": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": " sum (\n rate(\n nginx_ingress_controller_request_duration_seconds_count{\n ingress =~ \"$ingress\",\n status =~\"[4-5].*\",\n }[1m]\n )\n ) by(path, status)\n", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ path }} {{ status }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Response error volume by Path", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "reqps", + "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": 24 + }, + "hiddenSeries": false, + "id": 99, + "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": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (\n rate (\n nginx_ingress_controller_response_size_sum {\n ingress =~ \"$ingress\",\n }[1m]\n )\n) by (path) / sum (\n rate(\n nginx_ingress_controller_response_size_count {\n ingress =~ \"$ingress\",\n }[1m]\n )\n) by (path)\n", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ path }}", + "refId": "D" + }, + { + "expr": " sum (rate(nginx_ingress_controller_response_size_bucket{\n ingress =~ \"$ingress\",\n }[1m])) by (le)\n", + "hide": true, + "legendFormat": "{{le}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average response size by Path", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "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": 8, + "w": 12, + "x": 0, + "y": 32 + }, + "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": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (\n rate(\n nginx_ingress_controller_ingress_upstream_latency_seconds_sum {\n ingress =~ \"$ingress\",\n }[1m]\n)) / sum (\n rate(\n nginx_ingress_controller_ingress_upstream_latency_seconds_count {\n ingress =~ \"$ingress\",\n }[1m]\n )\n)\n", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "average", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Upstream service latency", + "tooltip": { + "shared": true, + "sort": 0, + "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": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "30s", + "schemaVersion": 22, + "style": "dark", + "tags": [ + "nginx" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": ".*", + "current": {}, + "datasource": "$datasource", + "definition": "label_values(nginx_ingress_controller_requests, ingress) ", + "hide": 0, + "includeAll": true, + "label": "Service Ingress", + "multi": false, + "name": "ingress", + "options": [], + "query": "label_values(nginx_ingress_controller_requests, ingress) ", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "2m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "NGINX / Request Handling Performance", + "uid": "4GFbkOsZk", + "version": 1 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/cluster/rancher-cluster-nodes.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/cluster/rancher-cluster-nodes.json new file mode 100644 index 0000000000..d1cc3b70ac --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/cluster/rancher-cluster-nodes.json @@ -0,0 +1,793 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 28, + "links": [], + "panels": [ + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode=\"idle\"}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Load[5m] ({{instance}})" + }, + "properties": [] + } + ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_load1 OR avg_over_time(windows_system_processor_queue_length[1m])) by (instance)", + "interval": "", + "legendFormat": "Load[1m] ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(node_load5 OR avg_over_time(windows_system_processor_queue_length[5m])) by (instance)", + "interval": "", + "legendFormat": "Load[5m] ({{instance}})", + "refId": "B" + }, + { + "expr": "sum(node_load15 OR avg_over_time(windows_system_processor_queue_length[15m])) by (instance)", + "interval": "", + "legendFormat": "Load[15m] ({{instance}})", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Load Average", + "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": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - sum(node_memory_MemAvailable_bytes OR windows_os_physical_memory_free_bytes) by (instance) / sum(node_memory_MemTotal_bytes OR windows_cs_physical_memory_bytes) by (instance) ", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"} OR windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) by (instance) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"} OR windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) by (instance))", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_disk_read_bytes_total[$__rate_interval]) OR rate(windows_logical_disk_read_bytes_total[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Read ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(rate(node_disk_written_bytes_total[$__rate_interval]) OR rate(windows_logical_disk_write_bytes_total[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Write ({{instance}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 7 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_network_receive_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_received_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Receive Errors ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(rate(node_network_receive_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Receive Total ({{instance}})", + "refId": "B" + }, + { + "expr": "sum(rate(node_network_transmit_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_outbound_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Transmit Errors ({{instance}})", + "refId": "C" + }, + { + "expr": "sum(rate(node_network_receive_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_received_discarded_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Receive Dropped ({{instance}})", + "refId": "D" + }, + { + "expr": "sum(rate(node_network_transmit_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_outbound_discarded{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Transmit Dropped ({{instance}})", + "refId": "E" + }, + { + "expr": "sum(rate(node_network_transmit_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) by (instance) OR sum(rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Transmit Total ({{instance}})", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "pps", + "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": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval]) OR rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Transmit Total ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval]) OR rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Receive Total ({{instance}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Cluster (Nodes)", + "uid": "rancher-cluster-nodes-1", + "version": 3 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/cluster/rancher-cluster.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/cluster/rancher-cluster.json new file mode 100644 index 0000000000..ec977f55d1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/cluster/rancher-cluster.json @@ -0,0 +1,776 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 28, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode=\"idle\"}[$__rate_interval]))", + "legendFormat": "Total", + "interval": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Load[5m]" + }, + "properties": [] + } + ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_load1 OR avg_over_time(windows_system_processor_queue_length[1m]))", + "interval": "", + "legendFormat": "Load[1m]", + "refId": "A" + }, + { + "expr": "sum(node_load5 OR avg_over_time(windows_system_processor_queue_length[5m]))", + "interval": "", + "legendFormat": "Load[5m]", + "refId": "B" + }, + { + "expr": "sum(node_load15 OR avg_over_time(windows_system_processor_queue_length[15m]))", + "interval": "", + "legendFormat": "Load[15m]", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Load Average", + "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": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - sum(node_memory_MemAvailable_bytes OR windows_os_physical_memory_free_bytes) / sum(node_memory_MemTotal_bytes OR windows_cs_physical_memory_bytes)", + "legendFormat": "Total", + "interval": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"} OR windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"} OR windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}))", + "legendFormat": "Total", + "interval": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_disk_read_bytes_total[$__rate_interval]) OR rate(windows_logical_disk_read_bytes_total[$__rate_interval]))", + "interval": "", + "legendFormat": "Read", + "refId": "A" + }, + { + "expr": "sum(rate(node_disk_written_bytes_total[$__rate_interval]) OR rate(windows_logical_disk_write_bytes_total[$__rate_interval]))", + "interval": "", + "legendFormat": "Write", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + }, + { + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 7 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(rate(node_network_receive_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Receive Errors", + "refId": "A" + }, + { + "expr": "(sum(rate(node_network_receive_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Receive Total", + "refId": "B" + }, + { + "expr": "(sum(rate(node_network_transmit_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_outbound_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Transmit Errors", + "refId": "C" + }, + { + "expr": "(sum(rate(node_network_receive_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_discarded_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Receive Dropped", + "refId": "D" + }, + { + "expr": "(sum(rate(node_network_transmit_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_outbound_discarded{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Transmit Dropped", + "refId": "E" + }, + { + "expr": "(sum(rate(node_network_transmit_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Transmit Total", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "pps", + "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 + } + }, + { + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval]) OR rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval]))", + "interval": "", + "legendFormat": "Transmit Total", + "refId": "A" + }, + { + "expr": "sum(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\"}[$__rate_interval]) OR rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*'}[$__rate_interval]))", + "interval": "", + "legendFormat": "Receive Total", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Cluster", + "uid": "rancher-cluster-1", + "version": 3 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/bundle.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/bundle.json new file mode 100644 index 0000000000..698f48aeed --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/bundle.json @@ -0,0 +1,246 @@ +{ + "description": "Bundle", + "graphTooltip": 1, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 0 + }, + "id": 1, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Bundles", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 0 + }, + "id": 2, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_not_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_out_of_sync{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Out of Sync" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_err_applied{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Err Applied" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Modified" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_pending{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Pending" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_wait_applied{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Wait Applied" + } + ], + "title": "Bundles", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 3, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_not_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_out_of_sync{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Out of Sync" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_err_applied{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Err Applied" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Modified" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_pending{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Pending" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundle_wait_applied{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Wait Applied" + } + ], + "title": "Bundles", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "templating": { + "list": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "name": "namespace", + "query": "label_values(fleet_bundle_desired_ready, exported_namespace)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "includeAll": true, + "name": "name", + "query": "label_values(fleet_bundle_desired_ready{exported_namespace=~\"$namespace\"}, name)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Fleet / Bundle", + "uid": "fleet-bundle" +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/bundledeployment.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/bundledeployment.json new file mode 100644 index 0000000000..c81f7a6212 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/bundledeployment.json @@ -0,0 +1,219 @@ +{ + "description": "BundleDeployment", + "graphTooltip": 1, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 0 + }, + "id": 1, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Ready\"}) / sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\"})" + } + ], + "title": "Ready BundleDeployments", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 0 + }, + "id": 2, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Ready\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"NotReady\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"WaitApplied\"})", + "legendFormat": "Wait Applied" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"ErrApplied\"})", + "legendFormat": "Err Applied" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"OutOfSync\"})", + "legendFormat": "OutOfSync" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Pending\"})", + "legendFormat": "Pending" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Modified\"})", + "legendFormat": "Modified" + } + ], + "title": "BundleDeployments", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 3, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Ready\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"NotReady\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"WaitApplied\"})", + "legendFormat": "Wait Applied" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"ErrApplied\"})", + "legendFormat": "Err Applied" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"OutOfSync\"})", + "legendFormat": "OutOfSync" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Pending\"})", + "legendFormat": "Pending" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_bundledeployment_state{cluster_namespace=~\"$namespace\",state=\"Modified\"})", + "legendFormat": "Modified" + } + ], + "title": "BundleDeployments", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "templating": { + "list": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "name": "namespace", + "query": "label_values(fleet_bundledeployment_state, cluster_namespace)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Fleet / BundleDeployment", + "uid": "fleet-bundledeployment" +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/cluster.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/cluster.json new file mode 100644 index 0000000000..73bdea4834 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/cluster.json @@ -0,0 +1,484 @@ +{ + "description": "Cluster", + "graphTooltip": 1, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 0 + }, + "id": 1, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_cluster_desired_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Git Repos", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 0 + }, + "id": 2, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_desired_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + } + ], + "title": "Git Repos", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 3, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_desired_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_ready_git_repos{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + } + ], + "title": "Git Repos", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 13 + }, + "id": 4, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_cluster_resources_count_desiredready{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Resources", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 13 + }, + "id": 5, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_desiredready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_notready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Missing" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Modified" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Unknown" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_orphaned{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Orphaned" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_waitapplied{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Wait Applied" + } + ], + "title": "Resources", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 6, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_desiredready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_notready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Missing" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Modified" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Unknown" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_orphaned{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Orphaned" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_resources_count_waitapplied{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Wait Applied" + } + ], + "title": "Resources", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 26 + }, + "id": 7, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"Ready\"}) / sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Clusters", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 26 + }, + "id": 8, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"Ready\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"NotReady\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"WaitCheckIn\"})", + "legendFormat": "Wait Check In" + } + ], + "title": "Clusters", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 34 + }, + "id": 9, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"Ready\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"NotReady\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_state{exported_namespace=\"$namespace\",name=~\"$name\",state=\"WaitCheckIn\"})", + "legendFormat": "Wait Check In" + } + ], + "title": "Clusters", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "templating": { + "list": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "name": "namespace", + "query": "label_values(fleet_cluster_desired_ready_git_repos, exported_namespace)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "includeAll": true, + "name": "name", + "query": "label_values(fleet_cluster_desired_ready_git_repos{exported_namespace=~\"$namespace\"}, name)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Fleet / Cluster", + "uid": "fleet-cluster" +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/clustergroup.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/clustergroup.json new file mode 100644 index 0000000000..ce3df87b21 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/clustergroup.json @@ -0,0 +1,468 @@ +{ + "description": "ClusterGroup", + "graphTooltip": 1, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 0 + }, + "id": 1, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_cluster_group_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Bundles", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 0 + }, + "id": 2, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + } + ], + "title": "Bundles", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 3, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_bundle_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_bundle_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + } + ], + "title": "Bundles", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 13 + }, + "id": 4, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "(sum(fleet_cluster_group_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"}) - sum(fleet_cluster_group_non_ready_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})) / sum(fleet_cluster_group_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Clusters", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 13 + }, + "id": 5, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Total" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_non_ready_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Non Ready" + } + ], + "title": "Clusters", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 6, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Total" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_non_ready_cluster_count{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Non Ready" + } + ], + "title": "Clusters", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 26 + }, + "id": 7, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_cluster_group_resource_count_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Resources", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 26 + }, + "id": 8, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_notready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Missing" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Modified" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_orphaned{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Orphaned" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Unknown" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_waitapplied{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Wait Applied" + } + ], + "title": "Resources", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 34 + }, + "id": 9, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_notready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Missing" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Modified" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_orphaned{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Orphaned" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Unknown" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_cluster_group_resource_count_waitapplied{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Wait Applied" + } + ], + "title": "Resources", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "templating": { + "list": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "name": "namespace", + "query": "label_values(fleet_cluster_group_bundle_desired_ready, exported_namespace)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "includeAll": true, + "name": "name", + "query": "label_values(fleet_cluster_group_bundle_desired_ready{exported_namespace=~\"$namespace\"}, name)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Fleet / ClusterGroup", + "uid": "fleet-cluster-group" +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/controller-runtime.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/controller-runtime.json new file mode 100644 index 0000000000..23a81f2a8c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/controller-runtime.json @@ -0,0 +1,454 @@ +{ + "description": "Controller Runtime", + "graphTooltip": 1, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "controller_runtime_active_workers{job=\"$job\", namespace=\"$namespace\"}", + "legendFormat": "{{controller}} {{instance}}" + } + ], + "title": "Number of Workers in Use", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 2, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(controller_runtime_reconcile_errors_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", + "legendFormat": "{{instance}} {{pod}}" + } + ], + "title": "Reconciliation Error Count per Controller", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 3, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(controller_runtime_reconcile_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", + "legendFormat": "{{instance}} {{pod}}" + } + ], + "title": "Total Reconciliation Count per Controller", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 4, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "workqueue_depth{job=\"$job\", namespace=\"$namespace\"}", + "legendFormat": "{{instance}} {{pod}}" + } + ], + "title": "WorkQueue Depth", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 5, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "histogram_quantile(0.50, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", + "legendFormat": "P50 {{name}}" + } + ], + "title": "Seconds for Items Stay in Queue (before being requested) P50", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 40 + }, + "id": 6, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "histogram_quantile(0.90, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", + "legendFormat": "P90 {{name}}" + } + ], + "title": "Seconds for Items Stay in Queue (before being requested) P90", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 48 + }, + "id": 7, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", + "legendFormat": "P99 {{name}}" + } + ], + "title": "Seconds for Items Stay in Queue (before being requested) P99", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 56 + }, + "id": 8, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(workqueue_adds_total{job=\"$job\", namespace=\"$namespace\"}[2m])) by (instance, name)", + "legendFormat": "{{name}} {{instance}}" + } + ], + "title": "Work Queue Add Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 64 + }, + "id": 9, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "rate(workqueue_unfinished_work_seconds{job=\"$job\", namespace=\"$namespace\"}[5m])", + "legendFormat": "{{name}} {{instance}}" + } + ], + "title": "Unfinished Seconds", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 72 + }, + "id": 10, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "histogram_quantile(0.50, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", + "legendFormat": "P50 {{name}}" + } + ], + "title": "Seconds Processing Items from WorkQueue - 50th Percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 80 + }, + "id": 11, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "histogram_quantile(0.90, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", + "legendFormat": "P90 {{name}}" + } + ], + "title": "Seconds Processing Items from WorkQueue - 90th Percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 88 + }, + "id": 12, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "histogram_quantile(0.99, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", + "legendFormat": "P99 {{name}}" + } + ], + "title": "Seconds Processing Items from WorkQueue - 99th Percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": null, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 96 + }, + "id": 13, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(workqueue_retries_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name)", + "legendFormat": "{{name}} {{instance}}" + } + ], + "title": "Work Queue Retries Rate", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "templating": { + "list": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "name": "namespace", + "query": "label_values(controller_runtime_reconcile_total, namespace)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "name": "job", + "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Fleet / Controller-Runtime", + "uid": "fleet-controller-runtime" +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/gitrepo.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/gitrepo.json new file mode 100644 index 0000000000..1a50c2937d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/fleet/gitrepo.json @@ -0,0 +1,325 @@ +{ + "description": "GitRepo", + "graphTooltip": 1, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 0 + }, + "id": 1, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_gitrepo_desired_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Clusters", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 0 + }, + "id": 2, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_desired_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + } + ], + "title": "Clusters", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 3, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_desired_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_ready_clusters{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + } + ], + "title": "Clusters", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 5, + "w": 7, + "x": 0, + "y": 13 + }, + "id": 4, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_ready{exported_namespace=\"$namespace\",name=~\"$name\"}) / sum(fleet_gitrepo_resources_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})" + } + ], + "title": "Ready Resources", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 5, + "w": 17, + "x": 7, + "y": 13 + }, + "id": 5, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_not_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Missing" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Modified" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Unknown" + } + ], + "title": "Resources", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "decimals": 0, + "unit": null + } + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 6, + "pluginVersion": "v11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_desired_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Desired Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_not_ready{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Not Ready" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_missing{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Missing" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_modified{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Modified" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(fleet_gitrepo_resources_unknown{exported_namespace=\"$namespace\",name=~\"$name\"})", + "legendFormat": "Unknown" + } + ], + "title": "Resources", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "templating": { + "list": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "name": "namespace", + "query": "label_values(fleet_gitrepo_desired_ready_clusters, exported_namespace)", + "refresh": 2, + "type": "query" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "includeAll": true, + "name": "name", + "query": "label_values(fleet_gitrepo_desired_ready_clusters{exported_namespace=~\"$namespace\"}, name)", + "refresh": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Fleet / GitRepo", + "uid": "fleet-gitrepo" +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/home/rancher-default-home.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/home/rancher-default-home.json new file mode 100644 index 0000000000..3fce207561 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/home/rancher-default-home.json @@ -0,0 +1,1290 @@ +{ + "annotations": { + "list": [] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "title": "", + "type": "welcome" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 4 + }, + "height": "180px", + "id": 6, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "(1 - (avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode=\"idle\"}[5m])))) * 100", + "format": "time_series", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "65, 90", + "title": "CPU Utilization", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 4 + }, + "height": "180px", + "id": 4, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "(1 - sum({__name__=~\"node_memory_MemAvailable_bytes|windows_os_physical_memory_free_bytes\"}) / sum({__name__=~\"node_memory_MemTotal_bytes|windows_cs_physical_memory_bytes\"})) * 100", + "format": "time_series", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "65, 90", + "title": "Memory Utilization", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 5, + "w": 8, + "x": 16, + "y": 4 + }, + "height": "180px", + "id": 7, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "(1 - (((sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0))) / ((sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0))))) * 100", + "format": "time_series", + "interval": "10s", + "intervalFactor": 1, + "metric": "", + "refId": "A", + "step": 10 + } + ], + "thresholds": "65, 90", + "title": "Disk Utilization", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 0, + "y": 9 + }, + "height": "1px", + "id": 11, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": " cores", + "postfixFontSize": "30%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode!=\"idle\"}[5m]))", + "format": "time_series", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "title": "CPU Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 4, + "y": 9 + }, + "height": "1px", + "id": 12, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": " cores", + "postfixFontSize": "30%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kube_node_status_allocatable_cpu_cores{}) OR sum(kube_node_status_allocatable{resource=\"cpu\",unit=\"core\"})", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "title": "CPU Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 9 + }, + "height": "1px", + "id": 9, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "20%", + "prefix": "", + "prefixFontSize": "20%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum({__name__=~\"node_memory_MemTotal_bytes|windows_cs_physical_memory_bytes\"}) - sum({__name__=~\"node_memory_MemAvailable_bytes|windows_os_physical_memory_free_bytes\"})", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "title": "Memory Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 12, + "y": 9 + }, + "height": "1px", + "id": 10, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kube_node_status_allocatable_memory_bytes{}) OR sum(kube_node_status_allocatable{resource=\"memory\", unit=\"byte\"})", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "title": "Memory Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 9 + }, + "height": "1px", + "id": 13, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "(sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) - sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) - sum(windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0))", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "title": "Disk Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 20, + "y": 9 + }, + "height": "1px", + "id": 14, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "(sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0))", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "title": "Disk Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "0", + "value": "null" + } + ], + "valueName": "current" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 12 + }, + "hiddenSeries": false, + "id": 2051, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - (avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\",mode=\"idle\"}[$__rate_interval])))", + "format": "time_series", + "hide": false, + "instant": false, + "intervalFactor": 1, + "legendFormat": "Cluster", + "refId": "A" + }, + { + "expr": "1 - avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\", mode=\"idle\"}[$__rate_interval])) by (instance)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ instance }}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 12 + }, + "hiddenSeries": false, + "id": 2052, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "100 * (1 - sum({__name__=~\"node_memory_MemAvailable_bytes|windows_os_physical_memory_free_bytes\"}) / sum({__name__=~\"node_memory_MemTotal_bytes|windows_cs_physical_memory_bytes\"}))", + "format": "time_series", + "hide": false, + "instant": false, + "intervalFactor": 1, + "legendFormat": "Cluster", + "refId": "A" + }, + { + "expr": "100 * (1- sum({__name__=~\"node_memory_MemAvailable_bytes|windows_os_physical_memory_free_bytes\"}) by (instance) / sum({__name__=~\"node_memory_MemTotal_bytes|windows_cs_physical_memory_bytes\"}) by (instance))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ instance }}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 12 + }, + "hiddenSeries": false, + "id": 2053, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(1 - ((sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"} OR on() vector(0)))) / ((sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) OR on() vector(0)) + (sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) OR on() vector(0)))) * 100", + "legendFormat": "Cluster", + "refId": "A" + }, + { + "expr": "(1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\"}) by (instance)) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\"}) by (instance)) * 100", + "hide": false, + "legendFormat": "{{ instance }}", + "refId": "B" + }, + { + "expr": "(1 - (sum(windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) by (instance)) / sum(windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\"}) by (instance)) * 100", + "hide": false, + "legendFormat": "{{ instance }}", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "percent", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "folderId": 0, + "gridPos": { + "h": 15, + "w": 12, + "x": 0, + "y": 18 + }, + "headings": true, + "id": 3, + "limit": 30, + "links": [], + "query": "", + "recent": true, + "search": true, + "starred": false, + "tags": [], + "title": "Dashboards", + "type": "dashlist" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 2055, + "options": { + "content": "## About Rancher Monitoring\n\nRancher Monitoring is a Helm chart developed by Rancher that is powered by [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator). It is based on the upstream [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) Helm chart maintained by the Prometheus community.\n\nBy default, the chart deploys Grafana alongside a set of Grafana dashboards curated by the [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) project.\n\nFor more information on how Rancher Monitoring differs from [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack), please view the CHANGELOG.md of the rancher-monitoring chart located in the [rancher/charts](https://github.com/rancher/charts) repository.\n\nFor more information about how to configure Rancher Monitoring, please view the [Rancher docs](https://rancher.com/docs/rancher/v2.x/en/).\n\n", + "mode": "markdown" + }, + "pluginVersion": "7.1.0", + "timeFrom": null, + "timeShift": null, + "title": "", + "type": "text" + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "hidden": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "timezone": "browser", + "title": "Home", + "uid": "rancher-home-1", + "version": 5 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-etcd-nodes.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-etcd-nodes.json new file mode 100644 index 0000000000..8af4b81ce0 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-etcd-nodes.json @@ -0,0 +1,687 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 32, + "links": [], + "panels": [ + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(etcd_network_client_grpc_received_bytes_total{job=\"kube-etcd\"}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Client Traffic In ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(rate(etcd_network_client_grpc_sent_bytes_total{job=\"kube-etcd\"}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Client Traffic Out ({{instance}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "GRPC Client Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Load[5m]({{instance}})" + }, + "properties": [] + } + ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(etcd_mvcc_db_total_size_in_bytes) by (instance)", + "interval": "", + "legendFormat": "DB Size ({{instance}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "DB Size", + "tooltip": { + "shared": true, + "sort": 0, + "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": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(grpc_server_started_total{grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"}) by (instance) - sum(grpc_server_handled_total{grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"}) by (instance)", + "interval": "", + "legendFormat": "Watch Streams ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(grpc_server_started_total{grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"}) by (instance) - sum(grpc_server_handled_total{grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"}) by (instance)", + "interval": "", + "legendFormat": "Lease Watch Stream ({{instance}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Streams", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(etcd_server_proposals_committed_total[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Proposal Committed ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(rate(etcd_server_proposals_applied_total[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Proposal Applied ({{instance}})", + "refId": "B" + }, + { + "expr": "sum(rate(etcd_server_proposals_failed_total[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "Proposal Failed ({{instance}})", + "refId": "C" + }, + { + "expr": "sum(etcd_server_proposals_pending) by (instance)", + "interval": "", + "legendFormat": "Proposal Pending ({{instance}})", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Raft Proposals", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(grpc_server_started_total{grpc_type=\"unary\"}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "RPC Rate ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(rate(grpc_server_handled_total{grpc_type=\"unary\",grpc_code!=\"OK\"}[$__rate_interval])) by (instance)", + "interval": "", + "legendFormat": "RPC Failure Rate ({{instance}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "RPC Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 7 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_wal_fsync_duration_seconds_bucket[$__rate_interval])) by (instance, le))", + "interval": "", + "legendFormat": "WAL fsync ({{instance}})", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_backend_commit_duration_seconds_bucket[$__rate_interval])) by (instance, le))", + "interval": "", + "legendFormat": "DB fsync ({{instance}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Sync Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 2, + "format": "s", + "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 + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / etcd (Nodes)", + "uid": "rancher-etcd-nodes-1", + "version": 5 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-etcd.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-etcd.json new file mode 100644 index 0000000000..0c058cafb9 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-etcd.json @@ -0,0 +1,669 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 33, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(etcd_network_client_grpc_received_bytes_total{job=\"kube-etcd\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Client Traffic In", + "refId": "A" + }, + { + "expr": "sum(rate(etcd_network_client_grpc_sent_bytes_total{job=\"kube-etcd\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Client Traffic Out", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "GRPC Client Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "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": [ + { + "properties": [] + } + ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(etcd_mvcc_db_total_size_in_bytes)", + "interval": "", + "legendFormat": "DB Size", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "DB Size", + "tooltip": { + "shared": true, + "sort": 0, + "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": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(grpc_server_started_total{grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"}) - sum(grpc_server_handled_total{grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"})", + "interval": "", + "legendFormat": "Watch Streams", + "refId": "A" + }, + { + "expr": "sum(grpc_server_started_total{grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"}) - sum(grpc_server_handled_total{grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"})", + "interval": "", + "legendFormat": "Lease Watch Stream", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Streams", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(etcd_server_proposals_committed_total[$__rate_interval]))", + "interval": "", + "legendFormat": "Proposal Committed", + "refId": "A" + }, + { + "expr": "sum(rate(etcd_server_proposals_applied_total[$__rate_interval]))", + "interval": "", + "legendFormat": "Proposal Applied", + "refId": "B" + }, + { + "expr": "sum(rate(etcd_server_proposals_failed_total[$__rate_interval]))", + "interval": "", + "legendFormat": "Proposal Failed", + "refId": "C" + }, + { + "expr": "sum(etcd_server_proposals_pending)", + "interval": "", + "legendFormat": "Proposal Pending", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Raft Proposals", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(grpc_server_started_total{grpc_type=\"unary\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "RPC Rate", + "refId": "A" + }, + { + "expr": "sum(rate(grpc_server_handled_total{grpc_type=\"unary\",grpc_code!=\"OK\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "RPC Failure Rate", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "RPC Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 7 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_wal_fsync_duration_seconds_bucket[$__rate_interval])) by (instance, le))", + "interval": "", + "legendFormat": "WAL fsync", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_backend_commit_duration_seconds_bucket[$__rate_interval])) by (instance, le))", + "interval": "", + "legendFormat": "DB fsync", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Sync Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 2, + "format": "s", + "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 + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / etcd", + "uid": "rancher-etcd-1", + "version": 4 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-k8s-components-nodes.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-k8s-components-nodes.json new file mode 100644 index 0000000000..b31358eaaf --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-k8s-components-nodes.json @@ -0,0 +1,527 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 30, + "links": [], + "panels": [ + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(apiserver_request_total[$__rate_interval])) by (instance, code)", + "interval": "", + "legendFormat": "{{code}}({{instance}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "API Server Request Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "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": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Load[5m]({{instance}})" + }, + "properties": [] + } + ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"deployment\"}) by (instance, name)", + "interval": "", + "legendFormat": "Deployment Depth ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"volumes\"}) by (instance, name)", + "interval": "", + "legendFormat": "Volumes Depth ({{instance}})", + "refId": "B" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"replicaset\"}) by (instance, name)", + "interval": "", + "legendFormat": "ReplicaSet Depth ({{instance}})", + "refId": "C" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"service\"}) by (instance, name)", + "interval": "", + "legendFormat": "Service Depth ({{instance}})", + "refId": "D" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"serviceaccount\"}) by (instance, name)", + "interval": "", + "legendFormat": "ServiceAccount Depth ({{instance}})", + "refId": "E" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"endpoint\"}) by (instance, name)", + "interval": "", + "legendFormat": "Endpoint Depth ({{instance}})", + "refId": "F" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"daemonset\"}) by (instance, name)", + "interval": "", + "legendFormat": "DaemonSet Depth ({{instance}})", + "refId": "G" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"statefulset\"}) by (instance, name)", + "interval": "", + "legendFormat": "StatefulSet Depth ({{instance}})", + "refId": "H" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"replicationmanager\"}) by (instance, name)", + "interval": "", + "legendFormat": "ReplicationManager Depth ({{instance}})", + "refId": "I" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Controller Manager Queue Depth", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(kube_pod_status_scheduled{condition=\"false\"})", + "interval": "", + "legendFormat": "Failed To Schedule", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Pod Scheduling Status", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "{{instance}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"reading\"}) by (instance)", + "interval": "", + "legendFormat": "Reading ({{instance}})", + "refId": "A" + }, + { + "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"waiting\"}) by (instance)", + "interval": "", + "legendFormat": "Waiting ({{instance}})", + "refId": "B" + }, + { + "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"writing\"}) by (instance)", + "interval": "", + "legendFormat": "Writing ({{instance}})", + "refId": "C" + }, + { + "expr": "sum(ceil(increase(nginx_ingress_controller_nginx_process_connections_total{state=\"accepted\"}[$__rate_interval]))) by (instance)", + "interval": "", + "legendFormat": "Accepted ({{instance}})", + "refId": "D" + }, + { + "expr": "sum(ceil(increase(nginx_ingress_controller_nginx_process_connections_total{state=\"handled\"}[$__rate_interval]))) by (instance)", + "interval": "", + "legendFormat": "Handled ({{instance}})", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Ingress Controller Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Kubernetes Components (Nodes)", + "uid": "rancher-k8s-components-nodes-1", + "version": 5 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-k8s-components.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-k8s-components.json new file mode 100644 index 0000000000..44cf97f9fd --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/k8s/rancher-k8s-components.json @@ -0,0 +1,519 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 31, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(apiserver_request_total[$__rate_interval])) by (code)", + "interval": "", + "legendFormat": "{{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "API Server Request Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "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": [ + { + "matcher": { + "id": "byName", + "options": "Load[5m]({{instance}})" + }, + "properties": [] + } + ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"deployment\"}) by (name)", + "interval": "", + "legendFormat": "Deployment Depth", + "refId": "A" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"volumes\"}) by (name)", + "interval": "", + "legendFormat": "Volumes Depth", + "refId": "B" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"replicaset\"}) by (name)", + "interval": "", + "legendFormat": "Replicaset Depth", + "refId": "C" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"service\"}) by (name)", + "interval": "", + "legendFormat": "Service Depth", + "refId": "D" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"serviceaccount\"}) by (name)", + "interval": "", + "legendFormat": "ServiceAccount Depth", + "refId": "E" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"endpoint\"}) by (name)", + "interval": "", + "legendFormat": "Endpoint Depth", + "refId": "F" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"daemonset\"}) by (name)", + "interval": "", + "legendFormat": "DaemonSet Depth", + "refId": "G" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"statefulset\"}) by (name)", + "interval": "", + "legendFormat": "StatefulSet Depth", + "refId": "H" + }, + { + "expr": "sum(workqueue_depth{component=\"kube-controller-manager\", name=\"replicationmanager\"}) by (name)", + "interval": "", + "legendFormat": "ReplicationManager Depth", + "refId": "I" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Controller Manager Queue Depth", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "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": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(kube_pod_status_scheduled{condition=\"false\"})", + "interval": "", + "legendFormat": "Failed To Schedule", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Pod Scheduling Status", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "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": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"reading\"})", + "interval": "", + "legendFormat": "Reading", + "refId": "A" + }, + { + "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"waiting\"})", + "interval": "", + "legendFormat": "Waiting", + "refId": "B" + }, + { + "expr": "sum(nginx_ingress_controller_nginx_process_connections{state=\"writing\"})", + "interval": "", + "legendFormat": "Writing", + "refId": "C" + }, + { + "expr": "sum(ceil(increase(nginx_ingress_controller_nginx_process_connections_total{state=\"accepted\"}[$__rate_interval])))", + "interval": "", + "legendFormat": "Accepted", + "refId": "D" + }, + { + "expr": "sum(ceil(increase(nginx_ingress_controller_nginx_process_connections_total{state=\"handled\"}[$__rate_interval])))", + "interval": "", + "legendFormat": "Handled", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Ingress Controller Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Kubernetes Components", + "uid": "rancher-k8s-components-1", + "version": 5 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/logging/fluentbit.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/logging/fluentbit.json new file mode 100644 index 0000000000..b00582c8a8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/logging/fluentbit.json @@ -0,0 +1,760 @@ +{ + "annotations": { + "list": [ + { + "$$hashKey": "object:7", + "builtIn": 1, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Monitoring of the logging-stack", + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": 13042, + "graphTooltip": 1, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 19, + "panels": [], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "General", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1802", + "alias": "/Error.*/", + "color": "#E02F44" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "\nsum(rate(fluentbit_output_retries_total[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Retry rate", + "range": true, + "refId": "A" + }, + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(fluentbit_output_errors_total[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Error rate", + "range": true, + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Fluentbit output error/retry rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1697", + "format": "ops", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:1698", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Input and output total rates", + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 1 + }, + "hiddenSeries": false, + "id": 44, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(fluentbit_input_records_total[1m]))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "input", + "range": true, + "refId": "A" + }, + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(fluentbit_output_proc_records_total[1m]))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "output", + "range": true, + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Fluentbit input/output rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 30, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(fluentbit_output_retries_total[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "range": true, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current retry count", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 7 + }, + "hiddenSeries": false, + "id": 45, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(fluentbit_output_errors_total[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "range": true, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current error count", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 13 + }, + "hiddenSeries": false, + "id": 46, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(fluentbit_input_records_total[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "range": true, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Input records total", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 13 + }, + "hiddenSeries": false, + "id": 47, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(fluentbit_filter_drop_records_total[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "range": true, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Dropped records total", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "refresh": false, + "schemaVersion": 39, + "tags": [ + "logging", + "fluentbit" + ], + "templating": { + "list": [ + { + "hide": 2, + "name": "DS_PROMETHEUS", + "query": "prometheus", + "skipUrlSync": false, + "type": "constant" + } + ] + }, + "time": { + "from": "2024-08-20T15:06:03.311Z", + "to": "2024-08-20T21:06:03.311Z" + }, + "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": "Rancher / Fluentbit", + "uid": "rancher-logging-fluentbit", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/logging/fluentd.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/logging/fluentd.json new file mode 100644 index 0000000000..8861425ce1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/logging/fluentd.json @@ -0,0 +1,3221 @@ +{ + "annotations": { + "list": [ + { + "$$hashKey": "object:7", + "builtIn": 1, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Monitoring of the logging-stack", + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": 13042, + "graphTooltip": 1, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 19, + "panels": [], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "General", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "If you see errors then you probbaly have serious issues with log processing, see https://docs.fluentd.org/buffer#handling-unrecoverable-errors\n\nRetries are normal but should occur only from time to time, otherwise check for network errors or destination is too slow and requires additional tuning per given provider.", + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1802", + "alias": "/Error.*/", + "color": "#E02F44" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_retry_count[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Retry rate", + "refId": "A" + }, + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_num_errors[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Error rate", + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Fluentd output error/retry rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1697", + "format": "ops", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:1698", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "Input and output total rates", + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 1 + }, + "hiddenSeries": false, + "id": 44, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_input_status_num_records_total[1m]))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "input", + "refId": "A" + }, + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_write_count[1m]))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "output", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Fluentd input/output rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "This should not reach 0 otherwise logs are blocked from processing or even dropped", + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 16, + "y": 1 + }, + "hiddenSeries": false, + "id": 20, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "min(fluentd_output_status_buffer_available_space_ratio)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "lowest across all hosts", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Fluentd output status buffer available space ratio", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:918", + "decimals": 0, + "format": "percent", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:919", + "decimals": 0, + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "total flush time", + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 6 + }, + "hiddenSeries": false, + "id": 21, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:906", + "alias": "count", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_flush_time_count[1m]))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "time", + "refId": "A" + }, + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_slow_flush_count[1m]))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "count", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Fluentd output status flush time count rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:400", + "decimals": 0, + "format": "ms", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:401", + "decimals": 0, + "format": "short", + "logBase": 1, + "min": "0", + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "Current total size of stage and queue buffers.\nfluentd_output_status_buffer_total_bytes", + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 6 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "alignAsTable": false, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_buffer_total_bytes) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current total size of stage and queue buffers", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:321", + "format": "bytes", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:322", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 16, + "y": 6 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.3.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_buffer_queue_length)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "total", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Fluentd output buffer queue", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1460", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:1461", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": true, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 11 + }, + "id": 17, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_input_status_num_records_total", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 12 + }, + "hiddenSeries": false, + "id": 39, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) ", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "total", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Input entries rate (total)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_input_status_num_records_total", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 12 + }, + "hiddenSeries": false, + "id": 47, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) by (hostname)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{hostname}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Input entries rate per hostname", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_input_status_num_records_total", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 18 + }, + "hiddenSeries": false, + "id": 60, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) by (namespace)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Input entries rate per namespace", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_input_status_num_records_total", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 18 + }, + "hiddenSeries": false, + "id": 48, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) by (instance)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Input entries rate per instance", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Input details", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 59, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_input_status_num_records_total", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 25 + }, + "hiddenSeries": false, + "id": 49, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_input_status_num_records_total[1m])) by (tag)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{tag}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Input entries rate per tag", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Input details (warning, very slow!)", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 41, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_buffer_stage_length", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 32 + }, + "hiddenSeries": false, + "id": 22, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_buffer_stage_length) by (pod, type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current length of stage buffers", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_buffer_stage_byte_size", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 32 + }, + "hiddenSeries": false, + "id": 23, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_buffer_stage_byte_size) by (pod, type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current total size of stage buffers", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "bytes", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Buffer stage", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 43, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 39 + }, + "hiddenSeries": false, + "id": 50, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "max_over_time(fluentd_output_status_buffer_queue_length[1m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Maximum buffer length in last 1min", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 39 + }, + "hiddenSeries": false, + "id": 25, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "max_over_time(fluentd_output_status_buffer_total_bytes[1m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Maximum buffer bytes in last 1min", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "bytes", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_buffer_queue_length", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 45 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_buffer_queue_length) by (pod, type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current length of queue buffers", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_queue_byte_size", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 45 + }, + "hiddenSeries": false, + "id": 51, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_queue_byte_size) by (pod, type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current total size of queue buffers", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "bytes", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Buffer queue", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 15 + }, + "id": 46, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_buffer_available_space_ratio", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 52 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_buffer_available_space_ratio) by (pod, type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Ratio of available space in buffer", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "percent", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Buffer space", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 53, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_retry_count", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 59 + }, + "hiddenSeries": false, + "id": 30, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_retry_count[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current retry counts", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_emit_records", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 59 + }, + "hiddenSeries": false, + "id": 33, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_emit_records[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current emit records", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_emit_count", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 65 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_emit_count[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current emit counts rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_rollback_count", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 65 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_rollback_count[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current rollback counts", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_write_count", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 71 + }, + "hiddenSeries": false, + "id": 34, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_write_count[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current write counts", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_slow_flush_count", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 71 + }, + "hiddenSeries": false, + "id": 37, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_slow_flush_count[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current slow flush counts", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_retry_wait", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 77 + }, + "hiddenSeries": false, + "id": 38, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_retry_wait[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current retry wait", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_flush_time_count", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 77 + }, + "hiddenSeries": false, + "id": 36, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_flush_time_count[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total flush time", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "ms", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Buffer retries", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 17 + }, + "id": 57, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_num_errors", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 84 + }, + "hiddenSeries": false, + "id": 31, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(rate(fluentd_output_status_num_errors[1m])) by (type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Current number of errors rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Buffer errors", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 55, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 91 + }, + "hiddenSeries": false, + "id": 29, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "fluentd_output_status_buffer_newest_timekey - fluentd_output_status_buffer_oldest_timekey", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Timekey diff", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_buffer_newest_timekey", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 91 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_buffer_newest_timekey) by (pod, type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Newest timekey in buffer", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "description": "fluentd_output_status_buffer_oldest_timekey", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 97 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": false, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(fluentd_output_status_buffer_oldest_timekey) by (pod, type)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}} {{ type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Oldest timekey in buffer", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:250", + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:251", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Buffer timekeys", + "type": "row" + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "fluentd", + "logging" + ], + "templating": { + "list": [ + { + "hide": 2, + "name": "DS_PROMETHEUS", + "query": "prometheus", + "skipUrlSync": false, + "type": "constant" + } + ] + }, + "time": { + "from": "now-3h", + "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": "Rancher / Fluentd", + "uid": "rancher-logging-fluentd", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/nodes/rancher-node-detail.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/nodes/rancher-node-detail.json new file mode 100644 index 0000000000..920fb94cf7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/nodes/rancher-node-detail.json @@ -0,0 +1,805 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 28, + "links": [], + "panels": [ + { + "aliasColors": { + "{{mode}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\", instance=\"$instance\"}[$__rate_interval])) by (mode)", + "interval": "", + "legendFormat": "{{mode}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Load[5m]" + }, + "properties": [] + } + ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_load5{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[5m]))", + "interval": "", + "legendFormat": "Load[5m]", + "refId": "A" + }, + { + "expr": "sum(node_load1{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[1m]))", + "interval": "", + "legendFormat": "Load[1m]", + "refId": "B" + }, + { + "expr": "sum(node_load15{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[15m]))", + "interval": "", + "legendFormat": "Load[15m]", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Load Average", + "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": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - (node_memory_MemAvailable_bytes{instance=~\"$instance\"} OR windows_os_physical_memory_free_bytes{instance=~\"$instance\"}) / (node_memory_MemTotal_bytes{instance=~\"$instance\"} OR windows_cs_physical_memory_bytes{instance=~\"$instance\"})", + "interval": "", + "legendFormat": "Total", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": { + "{{device}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\", instance=~\"$instance\"} OR windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\", instance=~\"$instance\"}) by (device) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\", instance=~\"$instance\"} OR windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\", instance=~\"$instance\"}) by (device))", + "interval": "", + "legendFormat": "{{device}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": { + "{{device}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_disk_read_bytes_total{instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_logical_disk_read_bytes_total{instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Read ({{device}})", + "refId": "A" + }, + { + "expr": "sum(rate(node_disk_written_bytes_total{instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_logical_disk_write_bytes_total{instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Write ({{device}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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": { + "{{device}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 7 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_network_receive_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_received_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Receive Errors ({{device}})", + "refId": "A" + }, + { + "expr": "sum(rate(node_network_receive_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Receive Total ({{device}})", + "refId": "B" + }, + { + "expr": "sum(rate(node_network_transmit_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_outbound_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Transmit Errors ({{device}})", + "refId": "C" + }, + { + "expr": "sum(rate(node_network_receive_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_received_discarded_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Receive Dropped ({{device}})", + "refId": "D" + }, + { + "expr": "sum(rate(node_network_transmit_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_outbound_discarded{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Transmit Dropped ({{device}})", + "refId": "E" + }, + { + "expr": "sum(rate(node_network_transmit_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) by (device) OR sum(rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Transmit Total ({{device}})", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "pps", + "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": { + "{{device}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Transmit Total ({{device}})", + "refId": "A" + }, + { + "expr": "sum(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) by (device)", + "interval": "", + "legendFormat": "Receive Total ({{device}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "instance", + "query": "label_values({__name__=~\"node_exporter_build_info|windows_exporter_build_info\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Node (Detail)", + "uid": "rancher-node-detail-1", + "version": 3 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/nodes/rancher-node.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/nodes/rancher-node.json new file mode 100644 index 0000000000..367df3cc9d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/nodes/rancher-node.json @@ -0,0 +1,792 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 28, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - avg(irate({__name__=~\"node_cpu_seconds_total|windows_cpu_time_total\", instance=\"$instance\", mode=\"idle\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Total", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Load[5m]" + }, + "properties": [] + } + ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_load5{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[5m]))", + "interval": "", + "legendFormat": "Load[5m]", + "refId": "A" + }, + { + "expr": "sum(node_load1{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[1m]))", + "interval": "", + "legendFormat": "Load[1m]", + "refId": "B" + }, + { + "expr": "sum(node_load15{instance=~\"$instance\"} OR avg_over_time(windows_system_processor_queue_length{instance=~\"$instance\"}[15m]))", + "interval": "", + "legendFormat": "Load[15m]", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Load Average", + "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": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - sum(node_memory_MemAvailable_bytes{instance=~\"$instance\"} OR windows_os_physical_memory_free_bytes{instance=~\"$instance\"}) / sum(node_memory_MemTotal_bytes{instance=~\"$instance\"} OR windows_cs_physical_memory_bytes{instance=~\"$instance\"})", + "interval": "", + "legendFormat": "Total", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - (sum(node_filesystem_free_bytes{device!~\"rootfs|HarddiskVolume.+\", instance=~\"$instance\"} OR windows_logical_disk_free_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\", instance=~\"$instance\"}) / sum(node_filesystem_size_bytes{device!~\"rootfs|HarddiskVolume.+\", instance=~\"$instance\"} OR windows_logical_disk_size_bytes{volume!~\"(HarddiskVolume.+|[A-Z]:.+)\", instance=~\"$instance\"}))", + "interval": "", + "legendFormat": "Total", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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 + } + }, + { + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_disk_read_bytes_total{instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_logical_disk_read_bytes_total{instance=~\"$instance\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Read", + "refId": "A" + }, + { + "expr": "sum(rate(node_disk_written_bytes_total{instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_logical_disk_write_bytes_total{instance=~\"$instance\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Write", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + }, + { + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 7 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(rate(node_network_receive_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Receive Errors", + "refId": "A" + }, + { + "expr": "(sum(rate(node_network_receive_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Receive Total", + "refId": "B" + }, + { + "expr": "(sum(rate(node_network_transmit_errs_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_outbound_errors_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Transmit Errors", + "refId": "C" + }, + { + "expr": "(sum(rate(node_network_receive_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_received_discarded_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Receive Dropped", + "refId": "D" + }, + { + "expr": "(sum(rate(node_network_transmit_drop_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_outbound_discarded{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Transmit Dropped", + "refId": "E" + }, + { + "expr": "(sum(rate(node_network_transmit_packets_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0)) + (sum(rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval])) OR on() vector(0))", + "interval": "", + "legendFormat": "Transmit Total", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "pps", + "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 + } + }, + { + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_net_packets_sent_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Transmit Total", + "refId": "A" + }, + { + "expr": "sum(rate(node_network_receive_bytes_total{device!~\"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*\", instance=~\"$instance\"}[$__rate_interval]) OR rate(windows_net_packets_received_total_total{nic!~'.*isatap.*|.*VPN.*|.*Pseudo.*|.*tunneling.*', instance=~\"$instance\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Receive Total", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "instance", + "query": "label_values({__name__=~\"node_exporter_build_info|windows_exporter_build_info\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Node", + "uid": "rancher-node-1", + "version": 3 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/performance/performance-debugging.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/performance/performance-debugging.json new file mode 100644 index 0000000000..454bc39390 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/performance/performance-debugging.json @@ -0,0 +1,1652 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 22, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (handler_name) (rate(lasso_controller_reconcile_time_seconds_sum[5m]))\n/\nsum by (handler_name) (rate(lasso_controller_reconcile_time_seconds_count[5m])))", + "interval": "", + "legendFormat": "{{handler_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Handler Average Execution Times Over Last 5 Minutes (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1390", + "format": "short", + "label": "Execution Time in Seconds", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1391", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 8 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (resource, method, code) (rate(steve_api_request_time_sum{resource!=\"subscribe\"}[5m]))\n/\nsum by (resource, method, code) (rate(steve_api_request_time_count{resource!=\"subscribe\"}[5m])))", + "interval": "", + "legendFormat": "{{resource}} {{method}} {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Rancher API Average Request Times Over Last 5 Minutes (Top 20) (Subscribes Omitted)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:178", + "format": "ms", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:179", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 30, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "rate(steve_api_request_time_sum{resource=\"subscribe\"}[5m])\n/\nrate(steve_api_request_time_count{resource=\"subscribe\"}[5m])", + "interval": "", + "legendFormat": "{{resource}} {{method}} {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Subscribe Average Request Times Over Last 5 Minutes", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:368", + "format": "ms", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:369", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 24 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,workqueue_depth)", + "interval": "", + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Lasso Controller Work Queue Depth (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1553", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1554", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 13, + "w": 16, + "x": 0, + "y": 32 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (id, resource, method, code) (steve_api_total_requests))", + "instant": false, + "interval": "", + "legendFormat": "{{id}} {{resource}} {{method}} {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Number of Rancher Requests (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:290", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:291", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 16, + "x": 0, + "y": 45 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (id, resource, method) (steve_api_total_requests{code!=\"200\",code!=\"201\"}))", + "interval": "", + "legendFormat": "{{id}} {{resource}} {{method}} {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Number of Failed Rancher API Requests (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:428", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:429", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 54 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (resource, method, code) (rate(k8s_proxy_store_request_time_sum[5m]))\n/\nsum by (resource, method, code) (rate(k8s_proxy_store_request_time_count[5m])))", + "interval": "", + "legendFormat": "{{resource}} {{method}} {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "K8s Proxy Store Average Request Times Over Last 5 Minutes (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:662", + "format": "ms", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:663", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 62 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (resource, method, code) (rate(k8s_proxy_client_request_time_sum[5m]))\n/\nsum by (resource, method, code) (rate(k8s_proxy_client_request_time_count[5m])))", + "interval": "", + "legendFormat": "{{resource}} {{method}} {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "K8s Proxy Client Average Request Times Over Last 5 Minutes (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1710", + "format": "ms", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1711", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 70 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,lasso_controller_total_cached_object)", + "interval": "", + "legendFormat": "{{kind}} {{version}} {{group}} {{pod}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Cached Objects by GroupVersionKind (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:744", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:745", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 78 + }, + "hiddenSeries": false, + "id": 12, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (handler_name) (\nlasso_controller_total_handler_execution\n))", + "interval": "", + "legendFormat": "{{handler_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Lasso Handler Executions (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:824", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:825", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 86 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20, sum by (handler_name,controller_name) (\nincrease(lasso_controller_total_handler_execution[2m])\n))", + "interval": "", + "legendFormat": "{{controller_name}}.{{handler_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Handler Executions Over Last 2 Minutes (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 94 + }, + "hiddenSeries": false, + "id": 20, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (handler_name) (\nlasso_controller_total_handler_execution{has_error=\"true\"}\n))", + "interval": "", + "legendFormat": "{{handler_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total Handler Executions with Error (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1230", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1231", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 102 + }, + "hiddenSeries": false, + "id": 34, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,sum by (handler_name,controller_name) (\nincrease(lasso_controller_total_handler_execution{has_error=\"true\"}[2m])\n))", + "interval": "", + "legendFormat": "{{controller_name}}.{{handler_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Handler Executions Over Last 2 Minutes (Top 20)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 110 + }, + "hiddenSeries": false, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "topk(20,session_server_total_transmit_bytes)", + "interval": "", + "legendFormat": "{{clientkey}} {{pod}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Data Transmitted by Remote Dialer Sessions (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1953", + "format": "decbytes", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1954", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 118 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "exemplar": true, + "expr": "session_server_total_transmit_error_bytes", + "interval": "", + "legendFormat": "{{clientkey}} {{pod}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Errors for Remote Dialer Sessions (Top 20)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2045", + "format": "ms", + "label": "Error Data", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:2046", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 126 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "editorMode": "code", + "exemplar": true, + "expr": "session_server_total_add_websocket_session - (session_server_total_remove_websocket_session or (0 * session_server_total_add_websocket_session))", + "interval": "", + "legendFormat": "{{clientkey}} {{pod}}", + "range": true, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Remote Dialer Active Connections (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2199", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:2200", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 134 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(session_server_total_remove_connections[$__rate_interval])", + "interval": "", + "legendFormat": "{{clientkey}} {{pod}}", + "range": true, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Remote Dialer Removed Connections Rate (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2199", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:2200", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 0, + "y": 142 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(session_server_total_add_connections[$__rate_interval])", + "interval": "", + "legendFormat": "{{clientkey}} {{pod}}", + "range": true, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Remote Dialer Added Connections Rate (Top 20)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2117", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:2118", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "schemaVersion": 37, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "includeAll": false, + "label": "Data Source", + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Rancher Performance Debugging", + "uid": "tfrfU0a7k", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/pods/rancher-pod-containers.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/pods/rancher-pod-containers.json new file mode 100644 index 0000000000..cf78a2204c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/pods/rancher-pod-containers.json @@ -0,0 +1,636 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 28, + "iteration": 1618265214337, + "links": [], + "panels": [ + { + "aliasColors": { + "{{container}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_cpu_cfs_throttled_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "CFS throttled ({{container}})", + "refId": "A" + }, + { + "expr": "sum(rate(container_cpu_system_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container) OR sum(rate(windows_container_cpu_usage_seconds_kernelmode{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "System ({{container}})", + "refId": "B" + }, + { + "expr": "sum(rate(container_cpu_usage_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container) OR sum(rate(windows_container_cpu_usage_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Total ({{container}})", + "refId": "C" + }, + { + "expr": "sum(rate(container_cpu_user_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container) OR sum(rate(windows_container_cpu_usage_seconds_usermode{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "User ({{container}})", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "cpu", + "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": { + "{{container}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"} OR windows_container_memory_usage_commit_bytes{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"}) by (container)", + "interval": "", + "legendFormat": "({{container}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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": { + "{{container}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_receive_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Receive Total ({{container}})", + "refId": "A" + }, + { + "expr": "sum(irate(container_network_transmit_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_transmit_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Transmit Total ({{container}})", + "refId": "B" + }, + { + "expr": "sum(irate(container_network_receive_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_receive_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Receive Dropped ({{container}})", + "refId": "C" + }, + { + "expr": "sum(irate(container_network_receive_errors_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Receive Errors ({{container}})", + "refId": "D" + }, + { + "expr": "sum(irate(container_network_transmit_errors_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Transmit Errors ({{container}})", + "refId": "E" + }, + { + "expr": "sum(irate(container_network_transmit_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_transmit_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Transmit Dropped ({{container}})", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "pps", + "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": { + "{{container}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_receive_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Receive Total ({{container}})", + "refId": "A" + }, + { + "expr": "sum(irate(container_network_transmit_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container) OR sum(irate(windows_container_network_transmit_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Transmit Total ({{container}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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": { + "{{container}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_fs_writes_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Write ({{container}})", + "refId": "A" + }, + { + "expr": "sum(rate(container_fs_reads_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) by (container)", + "interval": "", + "legendFormat": "Read ({{container}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + } + ], + "refresh": false, + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "query": "label_values(kube_pod_info{}, namespace)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "pod", + "query": "label_values(kube_pod_info{namespace=\"$namespace\"}, pod)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Pod (Containers)", + "uid": "rancher-pod-containers-1", + "version": 8 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/pods/rancher-pod.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/pods/rancher-pod.json new file mode 100644 index 0000000000..4859eccc74 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/pods/rancher-pod.json @@ -0,0 +1,636 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 28, + "iteration": 1618265214337, + "links": [], + "panels": [ + { + "aliasColors": { + "": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_cpu_cfs_throttled_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "CFS throttled", + "refId": "A" + }, + { + "expr": "sum(rate(container_cpu_system_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) OR sum(rate(windows_container_cpu_usage_seconds_kernelmode{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "System", + "refId": "B" + }, + { + "expr": "sum(rate(container_cpu_usage_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) OR sum(rate(windows_container_cpu_usage_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Total", + "refId": "C" + }, + { + "expr": "sum(rate(container_cpu_user_seconds_total{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval])) OR sum(rate(windows_container_cpu_usage_seconds_usermode{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "User", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "cpu", + "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": { + "": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"} OR windows_container_memory_usage_commit_bytes{container!=\"POD\",namespace=~\"$namespace\",pod=~\"$pod\", container!=\"\"})", + "interval": "", + "legendFormat": "Total", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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": { + "": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_receive_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Receive Total", + "refId": "A" + }, + { + "expr": "sum(irate(container_network_transmit_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_transmit_packets_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Transmit Total", + "refId": "B" + }, + { + "expr": "sum(irate(container_network_receive_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_receive_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Receive Dropped", + "refId": "C" + }, + { + "expr": "sum(irate(container_network_receive_errors_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Receive Errors", + "refId": "D" + }, + { + "expr": "sum(irate(container_network_transmit_errors_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Transmit Errors", + "refId": "E" + }, + { + "expr": "sum(irate(container_network_transmit_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_transmit_packets_dropped_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Transmit Dropped", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "pps", + "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": { + "": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_receive_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Receive Total", + "refId": "A" + }, + { + "expr": "sum(irate(container_network_transmit_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])) OR sum(irate(windows_container_network_transmit_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Transmit Total", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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": { + "": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_fs_writes_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Write", + "refId": "A" + }, + { + "expr": "sum(rate(container_fs_reads_bytes_total{namespace=~\"$namespace\",pod=~\"$pod\",container!=\"\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Read", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + } + ], + "refresh": false, + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "query": "label_values(kube_pod_info{}, namespace)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "pod", + "query": "label_values(kube_pod_info{namespace=\"$namespace\"}, pod)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Pod", + "uid": "rancher-pod-1", + "version": 8 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/workloads/rancher-workload-pods.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/workloads/rancher-workload-pods.json new file mode 100644 index 0000000000..92c0d24a6e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/workloads/rancher-workload-pods.json @@ -0,0 +1,652 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 28, + "iteration": 1618265214337, + "links": [], + "panels": [ + { + "aliasColors": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(rate(container_cpu_cfs_throttled_seconds_total{namespace=~\"$namespace\",container=\"\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "CFS throttled ({{pod}})", + "refId": "A" + }, + { + "expr": "(sum(rate(container_cpu_system_seconds_total{namespace=~\"$namespace\",container=\"\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_kernelmode{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "System ({{pod}})", + "refId": "B" + }, + { + "expr": "(sum(rate(container_cpu_usage_seconds_total{namespace=~\"$namespace\",container=\"\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Total ({{pod}})", + "refId": "C" + }, + { + "expr": "(sum(rate(container_cpu_user_seconds_total{namespace=~\"$namespace\",container=\"\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_usermode{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "User ({{pod}})", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "cpu", + "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": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(container_memory_working_set_bytes{namespace=~\"$namespace\",container=\"\"} OR windows_container_memory_usage_commit_bytes{namespace=~\"$namespace\"}) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "({{pod}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(irate(container_network_receive_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Receive Total ({{pod}})", + "refId": "A" + }, + { + "expr": "(sum(irate(container_network_transmit_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Transmit Total ({{pod}})", + "refId": "B" + }, + { + "expr": "(sum(irate(container_network_receive_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Receive Dropped ({{pod}})", + "refId": "C" + }, + { + "expr": "(sum(irate(container_network_receive_errors_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Receive Errors ({{pod}})", + "refId": "D" + }, + { + "expr": "(sum(irate(container_network_transmit_errors_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Transmit Errors ({{pod}})", + "refId": "E" + }, + { + "expr": "(sum(irate(container_network_transmit_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Transmit Dropped ({{pod}})", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "pps", + "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": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(irate(container_network_receive_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Receive Total ({{pod}})", + "refId": "A" + }, + { + "expr": "(sum(irate(container_network_transmit_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Transmit Total ({{pod}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(rate(container_fs_writes_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Write ({{pod}})", + "refId": "A" + }, + { + "expr": "(sum(rate(container_fs_reads_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"}", + "interval": "", + "legendFormat": "Read ({{pod}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + } + ], + "refresh": false, + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "query": "query_result(kube_pod_info{namespace!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", + "refresh": 2, + "regex": "/.*namespace=\"([^\"]*)\"/", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "kind", + "query": "query_result(kube_pod_info{namespace=\"$namespace\", created_by_kind!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", + "refresh": 2, + "regex": "/.*created_by_kind=\"([^\"]*)\"/", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "workload", + "query": "query_result(kube_pod_info{namespace=\"$namespace\", created_by_kind=\"$kind\", created_by_name!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", + "refresh": 2, + "regex": "/.*created_by_name=\"([^\"]*)\"/", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Workload (Pods)", + "uid": "rancher-workload-pods-1", + "version": 8 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/workloads/rancher-workload.json b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/workloads/rancher-workload.json new file mode 100644 index 0000000000..9f5317c2f0 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/rancher/workloads/rancher-workload.json @@ -0,0 +1,652 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 28, + "iteration": 1618265214337, + "links": [], + "panels": [ + { + "aliasColors": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum((sum(rate(container_cpu_cfs_throttled_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "CFS throttled", + "refId": "A" + }, + { + "expr": "sum((sum(rate(container_cpu_system_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_kernelmode{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "System", + "refId": "B" + }, + { + "expr": "sum((sum(rate(container_cpu_usage_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Total", + "refId": "C" + }, + { + "expr": "sum((sum(rate(container_cpu_user_seconds_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(rate(windows_container_cpu_usage_seconds_usermode{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "User", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "cpu", + "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": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum((sum(container_memory_working_set_bytes{namespace=~\"$namespace\"} OR windows_container_memory_usage_commit_bytes{namespace=~\"$namespace\"}) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Total", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Utilization", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "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": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum((sum(irate(container_network_receive_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Receive Total", + "refId": "A" + }, + { + "expr": "sum((sum(irate(container_network_transmit_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_packets_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Transmit Total", + "refId": "B" + }, + { + "expr": "sum((sum(irate(container_network_receive_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Receive Dropped", + "refId": "C" + }, + { + "expr": "sum((sum(irate(container_network_receive_errors_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Receive Errors", + "refId": "D" + }, + { + "expr": "sum((sum(irate(container_network_transmit_errors_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Transmit Errors", + "refId": "E" + }, + { + "expr": "sum((sum(irate(container_network_transmit_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_packets_dropped_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Transmit Dropped", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "pps", + "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": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum((sum(irate(container_network_receive_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_receive_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Receive Total", + "refId": "A" + }, + { + "expr": "sum((sum(irate(container_network_transmit_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod) OR sum(irate(windows_container_network_transmit_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Transmit Total", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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": { + "{{pod}}": "#3797d5" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum((sum(rate(container_fs_writes_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Write", + "refId": "A" + }, + { + "expr": "sum((sum(rate(container_fs_reads_bytes_total{namespace=~\"$namespace\"}[$__rate_interval])) by (pod)) * on(pod) kube_pod_info{namespace=~\"$namespace\", created_by_kind=\"$kind\", created_by_name=\"$workload\"})", + "interval": "", + "legendFormat": "Read", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "Bps", + "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 + } + } + ], + "refresh": false, + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "query": "query_result(kube_pod_info{namespace!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", + "refresh": 2, + "regex": "/.*namespace=\"([^\"]*)\"/", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "kind", + "query": "query_result(kube_pod_info{namespace=\"$namespace\", created_by_kind!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", + "refresh": 2, + "regex": "/.*created_by_kind=\"([^\"]*)\"/", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "workload", + "query": "query_result(kube_pod_info{namespace=\"$namespace\", created_by_kind=\"$kind\", created_by_name!=\"\"} * on(pod) group_right(namespace, created_by_kind, created_by_name) count({__name__=~\"container_.*|windows_container_.*\", pod!=\"\"}) by (pod))", + "refresh": 2, + "regex": "/.*created_by_name=\"([^\"]*)\"/", + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Rancher / Workload", + "uid": "rancher-workload-1", + "version": 8 +} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/upgrade/scripts/delete-workloads-with-old-labels.sh b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/upgrade/scripts/delete-workloads-with-old-labels.sh new file mode 100644 index 0000000000..89431e7132 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/files/upgrade/scripts/delete-workloads-with-old-labels.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e +set -x + +# node-exporter +kubectl delete daemonset -l app=prometheus-node-exporter,release=rancher-monitoring --ignore-not-found=true + +# prometheus-adapter +kubectl delete deployments -l app=prometheus-adapter,release=rancher-monitoring --ignore-not-found=true + +# kube-state-metrics +kubectl delete deployments -l app.kubernetes.io/instance=rancher-monitoring,app.kubernetes.io/name=kube-state-metrics --cascade=orphan --ignore-not-found=true +kubectl delete statefulsets -l app.kubernetes.io/instance=rancher-monitoring,app.kubernetes.io/name=kube-state-metrics --cascade=orphan --ignore-not-found=true diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/NOTES.txt b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/NOTES.txt new file mode 100644 index 0000000000..371f3ae398 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/NOTES.txt @@ -0,0 +1,4 @@ +{{ $.Chart.Name }} has been installed. Check its status by running: + kubectl --namespace {{ template "kube-prometheus-stack.namespace" . }} get pods -l "release={{ $.Release.Name }}" + +Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator. diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/_helpers.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/_helpers.tpl new file mode 100644 index 0000000000..b89b6434f1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/_helpers.tpl @@ -0,0 +1,472 @@ +# Rancher +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} + +{{- define "monitoring_registry" -}} + {{- $temp_registry := (include "system_default_registry" .) -}} + {{- if $temp_registry -}} + {{- trimSuffix "/" $temp_registry -}} + {{- else -}} + {{- .Values.global.imageRegistry -}} + {{- end -}} +{{- end -}} + +{{/* +https://github.com/helm/helm/issues/4535#issuecomment-477778391 +Usage: {{ include "call-nested" (list . "SUBCHART_NAME" "TEMPLATE") }} +e.g. {{ include "call-nested" (list . "grafana" "grafana.fullname") }} +*/}} +{{- define "call-nested" }} +{{- $dot := index . 0 }} +{{- $subchart := index . 1 | splitList "." }} +{{- $template := index . 2 }} +{{- $values := $dot.Values }} +{{- range $subchart }} +{{- $values = index $values . }} +{{- end }} +{{- include $template (dict "Chart" (dict "Name" (last $subchart)) "Values" $values "Release" $dot.Release "Capabilities" $dot.Capabilities) }} +{{- end }} + +# Special Exporters +{{- define "exporter.kubeEtcd.enabled" -}} +{{- if or .Values.kubeEtcd.enabled .Values.rkeEtcd.enabled .Values.kubeAdmEtcd.enabled .Values.rke2Etcd.enabled -}} +"true" +{{- end -}} +{{- end }} + +{{- define "exporter.kubeControllerManager.enabled" -}} +{{- if or .Values.kubeControllerManager.enabled .Values.rkeControllerManager.enabled .Values.k3sServer.enabled .Values.kubeAdmControllerManager.enabled .Values.rke2ControllerManager.enabled -}} +"true" +{{- end -}} +{{- end }} + +{{- define "exporter.kubeScheduler.enabled" -}} +{{- if or .Values.kubeScheduler.enabled .Values.rkeScheduler.enabled .Values.k3sServer.enabled .Values.kubeAdmScheduler.enabled .Values.rke2Scheduler.enabled -}} +"true" +{{- end -}} +{{- end }} + +{{- define "exporter.kubeProxy.enabled" -}} +{{- if or .Values.kubeProxy.enabled .Values.rkeProxy.enabled .Values.k3sServer.enabled .Values.kubeAdmProxy.enabled .Values.rke2Proxy.enabled -}} +"true" +{{- end -}} +{{- end }} + +{{- define "exporter.kubelet.enabled" -}} +{{- if or .Values.kubelet.enabled .Values.hardenedKubelet.enabled .Values.k3sServer.enabled -}} +"true" +{{- end -}} +{{- end }} + +{{- define "exporter.kubeControllerManager.jobName" -}} +{{- if .Values.k3sServer.enabled -}} +k3s-server +{{- else -}} +kube-controller-manager +{{- end -}} +{{- end }} + +{{- define "exporter.kubeScheduler.jobName" -}} +{{- if .Values.k3sServer.enabled -}} +k3s-server +{{- else -}} +kube-scheduler +{{- end -}} +{{- end }} + +{{- define "exporter.kubeProxy.jobName" -}} +{{- if .Values.k3sServer.enabled -}} +k3s-server +{{- else -}} +kube-proxy +{{- end -}} +{{- end }} + +{{- define "exporter.kubelet.jobName" -}} +{{- if .Values.k3sServer.enabled -}} +k3s-server +{{- else -}} +kubelet +{{- end -}} +{{- end }} + +{{- define "kubelet.serviceMonitor.resourcePath" -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if not (eq .Values.kubelet.serviceMonitor.resourcePath "/metrics/resource/v1alpha1") -}} +{{ .Values.kubelet.serviceMonitor.resourcePath }} +{{- else if semverCompare ">=1.20.0-0" $kubeTargetVersion -}} +/metrics/resource +{{- else -}} +/metrics/resource/v1alpha1 +{{- end -}} +{{- end }} + +{{- define "rancher.serviceMonitor.selector" -}} +{{- if .Values.rancherMonitoring.selector }} +{{ .Values.rancherMonitoring.selector | toYaml }} +{{- else }} +{{- $rancherDeployment := (lookup "apps/v1" "Deployment" "cattle-system" "rancher") }} +{{- if $rancherDeployment }} +matchLabels: + app: rancher + chart: {{ index $rancherDeployment.metadata.labels "chart" }} + release: rancher +{{- end }} +{{- end }} +{{- end }} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} + +# Prometheus Operator + +{{/* vim: set filetype=mustache: */}} +{{/* Expand the name of the chart. This is suffixed with -alertmanager, which means subtract 13 from longest 63 available */}} +{{- define "kube-prometheus-stack.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 50 | 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. +The components in this chart create additional resources that expand the longest created name strings. +The longest name that gets created adds and extra 37 characters, so truncation should be 63-35=26. +*/}} +{{- define "kube-prometheus-stack.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 26 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 26 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 26 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* Fullname suffixed with -operator */}} +{{/* Adding 9 to 26 truncation of kube-prometheus-stack.fullname */}} +{{- define "kube-prometheus-stack.operator.fullname" -}} +{{- if .Values.prometheusOperator.fullnameOverride -}} +{{- .Values.prometheusOperator.fullnameOverride | trunc 35 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-operator" (include "kube-prometheus-stack.fullname" .) -}} +{{- end }} +{{- end }} + +{{/* Prometheus custom resource instance name */}} +{{- define "kube-prometheus-stack.prometheus.crname" -}} +{{- if .Values.cleanPrometheusOperatorObjectNames }} +{{- include "kube-prometheus-stack.fullname" . }} +{{- else }} +{{- print (include "kube-prometheus-stack.fullname" .) "-prometheus" }} +{{- end }} +{{- end }} + +{{/* Prometheus apiVersion for networkpolicy */}} +{{- define "kube-prometheus-stack.prometheus.networkPolicy.apiVersion" -}} +{{- print "networking.k8s.io/v1" -}} +{{- end }} + +{{/* Alertmanager custom resource instance name */}} +{{- define "kube-prometheus-stack.alertmanager.crname" -}} +{{- if .Values.cleanPrometheusOperatorObjectNames }} +{{- include "kube-prometheus-stack.fullname" . }} +{{- else }} +{{- print (include "kube-prometheus-stack.fullname" .) "-alertmanager" -}} +{{- end }} +{{- end }} + +{{/* ThanosRuler custom resource instance name */}} +{{/* Subtracting 1 from 26 truncation of kube-prometheus-stack.fullname */}} +{{- define "kube-prometheus-stack.thanosRuler.crname" -}} +{{- if .Values.cleanPrometheusOperatorObjectNames }} +{{- include "kube-prometheus-stack.fullname" . }} +{{- else }} +{{- print (include "kube-prometheus-stack.fullname" . | trunc 25 | trimSuffix "-") "-thanos-ruler" -}} +{{- end }} +{{- end }} + +{{/* Shortened name suffixed with thanos-ruler */}} +{{- define "kube-prometheus-stack.thanosRuler.name" -}} +{{- default (printf "%s-thanos-ruler" (include "kube-prometheus-stack.name" .)) .Values.thanosRuler.name -}} +{{- end }} + + +{{/* Create chart name and version as used by the chart label. */}} +{{- define "kube-prometheus-stack.chartref" -}} +{{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}} +{{- end }} + +{{/* Generate basic labels */}} +{{- define "kube-prometheus-stack.labels" }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: "{{ replace "+" "_" .Chart.Version }}" +app.kubernetes.io/part-of: {{ template "kube-prometheus-stack.name" . }} +chart: {{ template "kube-prometheus-stack.chartref" . }} +release: {{ $.Release.Name | quote }} +heritage: {{ $.Release.Service | quote }} +{{- if .Values.commonLabels}} +{{ toYaml .Values.commonLabels }} +{{- end }} +{{- end }} + +{{/* Create the name of kube-prometheus-stack service account to use */}} +{{- define "kube-prometheus-stack.operator.serviceAccountName" -}} +{{- if .Values.prometheusOperator.serviceAccount.create -}} + {{ default (include "kube-prometheus-stack.operator.fullname" .) .Values.prometheusOperator.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.prometheusOperator.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* Create the name of kube-prometheus-stack service account to use */}} +{{- define "kube-prometheus-stack.operator.admissionWebhooks.serviceAccountName" -}} +{{- if .Values.prometheusOperator.serviceAccount.create -}} + {{ default (printf "%s-webhook" (include "kube-prometheus-stack.operator.fullname" .)) .Values.prometheusOperator.admissionWebhooks.deployment.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.prometheusOperator.admissionWebhooks.deployment.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* Create the name of prometheus service account to use */}} +{{- define "kube-prometheus-stack.prometheus.serviceAccountName" -}} +{{- if .Values.prometheus.serviceAccount.create -}} + {{ default (print (include "kube-prometheus-stack.fullname" .) "-prometheus") .Values.prometheus.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.prometheus.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* Create the name of alertmanager service account to use */}} +{{- define "kube-prometheus-stack.alertmanager.serviceAccountName" -}} +{{- if .Values.alertmanager.serviceAccount.create -}} + {{ default (print (include "kube-prometheus-stack.fullname" .) "-alertmanager") .Values.alertmanager.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.alertmanager.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* Create the name of thanosRuler service account to use */}} +{{- define "kube-prometheus-stack.thanosRuler.serviceAccountName" -}} +{{- if .Values.thanosRuler.serviceAccount.create -}} + {{ default (include "kube-prometheus-stack.thanosRuler.name" .) .Values.thanosRuler.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.thanosRuler.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "kube-prometheus-stack.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Use the grafana namespace override for multi-namespace deployments in combined charts +*/}} +{{- define "kube-prometheus-stack-grafana.namespace" -}} + {{- if .Values.grafana.namespaceOverride -}} + {{- .Values.grafana.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Allow kube-state-metrics job name to be overridden +*/}} +{{- define "kube-prometheus-stack-kube-state-metrics.name" -}} + {{- if index .Values "kube-state-metrics" "nameOverride" -}} + {{- index .Values "kube-state-metrics" "nameOverride" -}} + {{- else -}} + {{- print "kube-state-metrics" -}} + {{- end -}} +{{- end -}} + +{{/* +Use the kube-state-metrics namespace override for multi-namespace deployments in combined charts +*/}} +{{- define "kube-prometheus-stack-kube-state-metrics.namespace" -}} + {{- if index .Values "kube-state-metrics" "namespaceOverride" -}} + {{- index .Values "kube-state-metrics" "namespaceOverride" -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Use the prometheus-node-exporter namespace override for multi-namespace deployments in combined charts +*/}} +{{- define "kube-prometheus-stack-prometheus-node-exporter.namespace" -}} + {{- if index .Values "prometheus-node-exporter" "namespaceOverride" -}} + {{- index .Values "prometheus-node-exporter" "namespaceOverride" -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* Allow KubeVersion to be overridden. */}} +{{- define "kube-prometheus-stack.kubeVersion" -}} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}} +{{- end -}} + +{{/* Get Ingress API Version */}} +{{- define "kube-prometheus-stack.ingress.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" (include "kube-prometheus-stack.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 -}} + +{{/* Check Ingress stability */}} +{{- define "kube-prometheus-stack.ingress.isStable" -}} + {{- eq (include "kube-prometheus-stack.ingress.apiVersion" .) "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* Check Ingress supports pathType */}} +{{/* pathType was added to networking.k8s.io/v1beta1 in Kubernetes 1.18 */}} +{{- define "kube-prometheus-stack.ingress.supportsPathType" -}} + {{- or (eq (include "kube-prometheus-stack.ingress.isStable" .) "true") (and (eq (include "kube-prometheus-stack.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" (include "kube-prometheus-stack.kubeVersion" .))) -}} +{{- end -}} + +{{/* Get Policy API Version */}} +{{- define "kube-prometheus-stack.pdb.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">= 1.21-0" (include "kube-prometheus-stack.kubeVersion" .)) -}} + {{- print "policy/v1" -}} + {{- else -}} + {{- print "policy/v1beta1" -}} + {{- end -}} + {{- end -}} + +{{/* Get value based on current Kubernetes version */}} +{{- define "kube-prometheus-stack.kubeVersionDefaultValue" -}} + {{- $values := index . 0 -}} + {{- $kubeVersion := index . 1 -}} + {{- $old := index . 2 -}} + {{- $new := index . 3 -}} + {{- $default := index . 4 -}} + {{- if kindIs "invalid" $default -}} + {{- if semverCompare $kubeVersion (include "kube-prometheus-stack.kubeVersion" $values) -}} + {{- print $new -}} + {{- else -}} + {{- print $old -}} + {{- end -}} + {{- else -}} + {{- print $default }} + {{- end -}} +{{- end -}} + +{{/* Get value for kube-controller-manager depending on insecure scraping availability */}} +{{- define "kube-prometheus-stack.kubeControllerManager.insecureScrape" -}} + {{- $values := index . 0 -}} + {{- $insecure := index . 1 -}} + {{- $secure := index . 2 -}} + {{- $userValue := index . 3 -}} + {{- include "kube-prometheus-stack.kubeVersionDefaultValue" (list $values ">= 1.22-0" $insecure $secure $userValue) -}} +{{- end -}} + +{{/* Get value for kube-scheduler depending on insecure scraping availability */}} +{{- define "kube-prometheus-stack.kubeScheduler.insecureScrape" -}} + {{- $values := index . 0 -}} + {{- $insecure := index . 1 -}} + {{- $secure := index . 2 -}} + {{- $userValue := index . 3 -}} + {{- include "kube-prometheus-stack.kubeVersionDefaultValue" (list $values ">= 1.23-0" $insecure $secure $userValue) -}} +{{- end -}} + +{{/* Sets default scrape limits for servicemonitor */}} +{{- define "servicemonitor.scrapeLimits" -}} +{{- with .sampleLimit }} +sampleLimit: {{ . }} +{{- end }} +{{- with .targetLimit }} +targetLimit: {{ . }} +{{- end }} +{{- with .labelLimit }} +labelLimit: {{ . }} +{{- end }} +{{- with .labelNameLengthLimit }} +labelNameLengthLimit: {{ . }} +{{- end }} +{{- with .labelValueLengthLimit }} +labelValueLengthLimit: {{ . }} +{{- end }} +{{- end -}} + +{{/* +To help compatibility with other charts which use global.imagePullSecrets. +Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). +global: + imagePullSecrets: + - name: pullSecret1 + - name: pullSecret2 + +or + +global: + imagePullSecrets: + - pullSecret1 + - pullSecret2 +*/}} +{{- define "kube-prometheus-stack.imagePullSecrets" -}} +{{- range .Values.global.imagePullSecrets }} + {{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml . | trim }} + {{- else }} +- name: {{ . }} + {{- end }} +{{- end }} +{{- end -}} + +{{- define "kube-prometheus-stack.operator.admission-webhook.dnsNames" }} +{{- $fullname := include "kube-prometheus-stack.operator.fullname" . }} +{{- $namespace := include "kube-prometheus-stack.namespace" . }} +{{- $fullname }} +{{ $fullname }}.{{ $namespace }}.svc +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.enabled }} +{{ $fullname }}-webhook +{{ $fullname }}-webhook.{{ $namespace }}.svc +{{- end }} +{{- end }} + +{{ - define "rke2-ingress-nginx.namespace" -}} + {{- if .Values.rke2IngressNginx.namespaceOverride -}} + {{- .Values.rke2IngressNginx.namespaceOverride -}} + {{- else -}} + {{- print "kube-system" -}} + {{- end -}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/alertmanager.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/alertmanager.yaml new file mode 100644 index 0000000000..fdc9a8af61 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/alertmanager.yaml @@ -0,0 +1,195 @@ +{{- if .Values.alertmanager.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: Alertmanager +metadata: + name: {{ template "kube-prometheus-stack.alertmanager.crname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.alertmanager.annotations }} + annotations: +{{ toYaml .Values.alertmanager.annotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.alertmanager.alertmanagerSpec.image }} + {{- $registry := include "monitoring_registry" . | default .Values.alertmanager.alertmanagerSpec.image.registry }} + {{- if and .Values.alertmanager.alertmanagerSpec.image.tag .Values.alertmanager.alertmanagerSpec.image.sha }} + image: "{{ $registry }}/{{ .Values.alertmanager.alertmanagerSpec.image.repository }}:{{ .Values.alertmanager.alertmanagerSpec.image.tag }}@sha256:{{ .Values.alertmanager.alertmanagerSpec.image.sha }}" + {{- else if .Values.alertmanager.alertmanagerSpec.image.sha }} + image: "{{ $registry }}/{{ .Values.alertmanager.alertmanagerSpec.image.repository }}@sha256:{{ .Values.alertmanager.alertmanagerSpec.image.sha }}" + {{- else if .Values.alertmanager.alertmanagerSpec.image.tag }} + image: "{{ $registry }}/{{ .Values.alertmanager.alertmanagerSpec.image.repository }}:{{ .Values.alertmanager.alertmanagerSpec.image.tag }}" + {{- else }} + image: "{{ $registry }}/{{ .Values.alertmanager.alertmanagerSpec.image.repository }}" + {{- end }} + version: {{ default .Values.alertmanager.alertmanagerSpec.image.tag .Values.alertmanager.alertmanagerSpec.version }} + {{- if .Values.alertmanager.alertmanagerSpec.image.sha }} + sha: {{ .Values.alertmanager.alertmanagerSpec.image.sha }} + {{- end }} +{{- end }} + replicas: {{ .Values.alertmanager.alertmanagerSpec.replicas }} + listenLocal: {{ .Values.alertmanager.alertmanagerSpec.listenLocal }} + serviceAccountName: {{ template "kube-prometheus-stack.alertmanager.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.alertmanager.alertmanagerSpec.automountServiceAccountToken }} +{{- if .Values.alertmanager.alertmanagerSpec.externalUrl }} + externalUrl: "{{ tpl .Values.alertmanager.alertmanagerSpec.externalUrl . }}" +{{- else if and .Values.alertmanager.ingress.enabled .Values.alertmanager.ingress.hosts }} + externalUrl: "http://{{ tpl (index .Values.alertmanager.ingress.hosts 0) . }}{{ .Values.alertmanager.alertmanagerSpec.routePrefix }}" +{{- else if not (or (kindIs "invalid" .Values.global.cattle.url) (kindIs "invalid" .Values.global.cattle.clusterId)) }} + externalUrl: "{{ .Values.global.cattle.url }}/k8s/clusters/{{ .Values.global.cattle.clusterId }}/api/v1/namespaces/{{ .Values.namespaceOverride }}/services/http:{{ template "kube-prometheus-stack.fullname" . }}-alertmanager:{{ .Values.alertmanager.service.port }}/proxy" +{{- else }} + externalUrl: http://{{ template "kube-prometheus-stack.fullname" . }}-alertmanager.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.alertmanager.service.port }} +{{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 4 }} +{{- if .Values.alertmanager.alertmanagerSpec.nodeSelector }} +{{ toYaml .Values.alertmanager.alertmanagerSpec.nodeSelector | indent 4 }} +{{- end }} + paused: {{ .Values.alertmanager.alertmanagerSpec.paused }} + logFormat: {{ .Values.alertmanager.alertmanagerSpec.logFormat | quote }} + logLevel: {{ .Values.alertmanager.alertmanagerSpec.logLevel | quote }} + retention: {{ .Values.alertmanager.alertmanagerSpec.retention | quote }} + {{- with .Values.alertmanager.enableFeatures }} + enableFeatures: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.secrets }} + secrets: +{{ toYaml .Values.alertmanager.alertmanagerSpec.secrets | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.configSecret }} + configSecret: {{ .Values.alertmanager.alertmanagerSpec.configSecret }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.configMaps }} + configMaps: +{{ toYaml .Values.alertmanager.alertmanagerSpec.configMaps | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.alertmanagerConfigSelector }} + alertmanagerConfigSelector: +{{ tpl (toYaml .Values.alertmanager.alertmanagerSpec.alertmanagerConfigSelector | indent 4) . }} +{{ else }} + alertmanagerConfigSelector: {} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.alertmanagerConfigNamespaceSelector }} + alertmanagerConfigNamespaceSelector: +{{ tpl (toYaml .Values.alertmanager.alertmanagerSpec.alertmanagerConfigNamespaceSelector | indent 4) . }} +{{ else }} + alertmanagerConfigNamespaceSelector: {} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.web }} + web: +{{ toYaml .Values.alertmanager.alertmanagerSpec.web | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.alertmanagerConfiguration }} + alertmanagerConfiguration: +{{ toYaml .Values.alertmanager.alertmanagerSpec.alertmanagerConfiguration | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.alertmanagerConfigMatcherStrategy }} + alertmanagerConfigMatcherStrategy: +{{ toYaml .Values.alertmanager.alertmanagerSpec.alertmanagerConfigMatcherStrategy | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.resources }} + resources: +{{ toYaml .Values.alertmanager.alertmanagerSpec.resources | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.routePrefix }} + routePrefix: "{{ .Values.alertmanager.alertmanagerSpec.routePrefix }}" +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.securityContext }} + securityContext: +{{ toYaml .Values.alertmanager.alertmanagerSpec.securityContext | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.storage }} + storage: +{{ tpl (toYaml .Values.alertmanager.alertmanagerSpec.storage | indent 4) . }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.podMetadata }} + podMetadata: +{{ toYaml .Values.alertmanager.alertmanagerSpec.podMetadata | indent 4 }} +{{- end }} +{{- if or .Values.alertmanager.alertmanagerSpec.podAntiAffinity .Values.alertmanager.alertmanagerSpec.affinity }} + affinity: +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.affinity }} +{{ toYaml .Values.alertmanager.alertmanagerSpec.affinity | indent 4 }} +{{- end }} +{{- if eq .Values.alertmanager.alertmanagerSpec.podAntiAffinity "hard" }} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: {{ .Values.alertmanager.alertmanagerSpec.podAntiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - {key: app.kubernetes.io/name, operator: In, values: [alertmanager]} + - {key: alertmanager, operator: In, values: [{{ template "kube-prometheus-stack.alertmanager.crname" . }}]} +{{- else if eq .Values.alertmanager.alertmanagerSpec.podAntiAffinity "soft" }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: {{ .Values.alertmanager.alertmanagerSpec.podAntiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - {key: app.kubernetes.io/name, operator: In, values: [alertmanager]} + - {key: alertmanager, operator: In, values: [{{ template "kube-prometheus-stack.alertmanager.crname" . }}]} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 4 }} +{{- if .Values.alertmanager.alertmanagerSpec.tolerations }} +{{ toYaml .Values.alertmanager.alertmanagerSpec.tolerations | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.alertmanager.alertmanagerSpec.topologySpreadConstraints | indent 4 }} +{{- end }} +{{- if .Values.global.imagePullSecrets }} + imagePullSecrets: +{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.containers }} + containers: +{{ toYaml .Values.alertmanager.alertmanagerSpec.containers | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.initContainers }} + initContainers: +{{ toYaml .Values.alertmanager.alertmanagerSpec.initContainers | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.priorityClassName }} + priorityClassName: {{.Values.alertmanager.alertmanagerSpec.priorityClassName }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.additionalPeers }} + additionalPeers: +{{ toYaml .Values.alertmanager.alertmanagerSpec.additionalPeers | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.volumes }} + volumes: +{{ toYaml .Values.alertmanager.alertmanagerSpec.volumes | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.volumeMounts }} + volumeMounts: +{{ toYaml .Values.alertmanager.alertmanagerSpec.volumeMounts | indent 4 }} +{{- end }} + portName: {{ .Values.alertmanager.alertmanagerSpec.portName }} +{{- if .Values.alertmanager.alertmanagerSpec.clusterAdvertiseAddress }} + clusterAdvertiseAddress: {{ .Values.alertmanager.alertmanagerSpec.clusterAdvertiseAddress }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.clusterGossipInterval }} + clusterGossipInterval: {{ .Values.alertmanager.alertmanagerSpec.clusterGossipInterval }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.clusterPeerTimeout }} + clusterPeerTimeout: {{ .Values.alertmanager.alertmanagerSpec.clusterPeerTimeout }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.clusterPushpullInterval }} + clusterPushpullInterval: {{ .Values.alertmanager.alertmanagerSpec.clusterPushpullInterval }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.forceEnableClusterMode }} + forceEnableClusterMode: {{ .Values.alertmanager.alertmanagerSpec.forceEnableClusterMode }} +{{- end }} +{{- if .Values.alertmanager.alertmanagerSpec.minReadySeconds }} + minReadySeconds: {{ .Values.alertmanager.alertmanagerSpec.minReadySeconds }} +{{- end }} +{{- with .Values.alertmanager.alertmanagerSpec.additionalConfig }} + {{- tpl (toYaml .) $ | nindent 2 }} +{{- end }} +{{- with .Values.alertmanager.alertmanagerSpec.additionalConfigString }} + {{- tpl . $ | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/extrasecret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/extrasecret.yaml new file mode 100644 index 0000000000..ecd8f47021 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/extrasecret.yaml @@ -0,0 +1,20 @@ +{{- if .Values.alertmanager.extraSecret.data -}} +{{- $secretName := printf "alertmanager-%s-extra" (include "kube-prometheus-stack.fullname" . ) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default $secretName .Values.alertmanager.extraSecret.name }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- if .Values.alertmanager.extraSecret.annotations }} + annotations: +{{ toYaml .Values.alertmanager.extraSecret.annotations | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager + app.kubernetes.io/component: alertmanager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: +{{- range $key, $val := .Values.alertmanager.extraSecret.data }} + {{ $key }}: {{ $val | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/ingress.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/ingress.yaml new file mode 100644 index 0000000000..be9f5aa279 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/ingress.yaml @@ -0,0 +1,78 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.ingress.enabled }} +{{- $pathType := .Values.alertmanager.ingress.pathType | default "ImplementationSpecific" }} +{{- $serviceName := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "alertmanager" }} +{{- $backendServiceName := .Values.alertmanager.ingress.serviceName | default (printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "alertmanager") }} +{{- $servicePort := .Values.alertmanager.ingress.servicePort | default .Values.alertmanager.service.port -}} +{{- $routePrefix := list .Values.alertmanager.alertmanagerSpec.routePrefix }} +{{- $paths := .Values.alertmanager.ingress.paths | default $routePrefix -}} +{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} +apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $serviceName }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- if .Values.alertmanager.ingress.annotations }} + annotations: + {{- tpl (toYaml .Values.alertmanager.ingress.annotations) . | nindent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager +{{- if .Values.alertmanager.ingress.labels }} +{{ toYaml .Values.alertmanager.ingress.labels | indent 4 }} +{{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + {{- if $apiIsStable }} + {{- if .Values.alertmanager.ingress.ingressClassName }} + ingressClassName: {{ .Values.alertmanager.ingress.ingressClassName }} + {{- end }} + {{- end }} + rules: + {{- if .Values.alertmanager.ingress.hosts }} + {{- range $host := .Values.alertmanager.ingress.hosts }} + - host: {{ tpl $host $ | quote }} + http: + paths: + {{- range $p := $paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ $backendServiceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $backendServiceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- else }} + - http: + paths: + {{- range $p := $paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ $backendServiceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $backendServiceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- if .Values.alertmanager.ingress.tls }} + tls: +{{ tpl (toYaml .Values.alertmanager.ingress.tls | indent 4) . }} + {{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/ingressperreplica.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/ingressperreplica.yaml new file mode 100644 index 0000000000..b2e00a4162 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/ingressperreplica.yaml @@ -0,0 +1,67 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.servicePerReplica.enabled .Values.alertmanager.ingressPerReplica.enabled }} +{{- $pathType := .Values.alertmanager.ingressPerReplica.pathType | default "" }} +{{- $count := .Values.alertmanager.alertmanagerSpec.replicas | int -}} +{{- $servicePort := .Values.alertmanager.service.port -}} +{{- $ingressValues := .Values.alertmanager.ingressPerReplica -}} +{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} +apiVersion: v1 +kind: List +metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-ingressperreplica + namespace: {{ template "kube-prometheus-stack.namespace" . }} +items: +{{ range $i, $e := until $count }} + - kind: Ingress + apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" $ }} + metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-{{ $i }} + namespace: {{ template "kube-prometheus-stack.namespace" $ }} + labels: + app: {{ include "kube-prometheus-stack.name" $ }}-alertmanager + {{ include "kube-prometheus-stack.labels" $ | indent 8 }} + {{- if $ingressValues.labels }} +{{ toYaml $ingressValues.labels | indent 8 }} + {{- end }} + {{- if $ingressValues.annotations }} + annotations: + {{- tpl (toYaml $ingressValues.annotations) $ | nindent 8 }} + {{- end }} + spec: + {{- if $apiIsStable }} + {{- if $ingressValues.ingressClassName }} + ingressClassName: {{ $ingressValues.ingressClassName }} + {{- end }} + {{- end }} + rules: + - host: {{ $ingressValues.hostPrefix }}-{{ $i }}.{{ $ingressValues.hostDomain }} + http: + paths: + {{- range $p := $ingressValues.paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-{{ $i }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-{{ $i }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- if or $ingressValues.tlsSecretName $ingressValues.tlsSecretPerReplica.enabled }} + tls: + - hosts: + - {{ $ingressValues.hostPrefix }}-{{ $i }}.{{ $ingressValues.hostDomain }} + {{- if $ingressValues.tlsSecretPerReplica.enabled }} + secretName: {{ $ingressValues.tlsSecretPerReplica.prefix }}-{{ $i }} + {{- else }} + secretName: {{ $ingressValues.tlsSecretName }} + {{- end }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/podDisruptionBudget.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/podDisruptionBudget.yaml new file mode 100644 index 0000000000..b183403125 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/podDisruptionBudget.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.podDisruptionBudget.enabled }} +apiVersion: {{ include "kube-prometheus-stack.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + {{- if .Values.alertmanager.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.alertmanager.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.alertmanager.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.alertmanager.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: alertmanager + alertmanager: {{ template "kube-prometheus-stack.alertmanager.crname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp-role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp-role.yaml new file mode 100644 index 0000000000..e8da52e0f4 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp-role.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.alertmanager.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +rules: +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} +- apiGroups: ['policy'] +{{- else }} +- apiGroups: ['extensions'] +{{- end }} + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-prometheus-stack.fullname" . }}-alertmanager +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp-rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp-rolebinding.yaml new file mode 100644 index 0000000000..71a8ec41dc --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp-rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.alertmanager.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager +subjects: + - kind: ServiceAccount + name: {{ template "kube-prometheus-stack.alertmanager.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp.yaml new file mode 100644 index 0000000000..5a940afab6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/psp.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.alertmanager.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager +{{- if .Values.global.rbac.pspAnnotations }} + annotations: +{{ toYaml .Values.global.rbac.pspAnnotations | indent 4 }} +{{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Permits the container to run with root privileges as well. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/secret.yaml new file mode 100644 index 0000000000..d4c397fa43 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/secret.yaml @@ -0,0 +1,37 @@ +{{- if and (.Values.alertmanager.enabled) (not .Values.alertmanager.alertmanagerSpec.useExistingSecret) }} +{{/* This file is applied when the operation is helm install and the target secret does not exist. */}} +{{- $secretName := (printf "alertmanager-%s" (include "kube-prometheus-stack.alertmanager.crname" .)) }} +{{- if or (not (lookup "v1" "Secret" (include "kube-prometheus-stack.namespace" .) $secretName)) (eq .Values.alertmanager.secret.recreateIfExists true) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": pre-install, pre-upgrade + "helm.sh/hook-weight": "3" + "helm.sh/resource-policy": keep +{{- if .Values.alertmanager.secret.annotations }} + annotations: +{{ toYaml .Values.alertmanager.secret.annotations | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: +{{- if .Values.alertmanager.tplConfig }} +{{- if .Values.alertmanager.stringConfig }} + alertmanager.yaml: {{ tpl (.Values.alertmanager.stringConfig) . | b64enc | quote }} +{{- else if eq (typeOf .Values.alertmanager.config) "string" }} + alertmanager.yaml: {{ tpl (.Values.alertmanager.config) . | b64enc | quote }} +{{- else }} + alertmanager.yaml: {{ tpl (toYaml .Values.alertmanager.config) . | b64enc | quote }} +{{- end }} +{{- else }} + alertmanager.yaml: {{ toYaml .Values.alertmanager.config | b64enc | quote }} +{{- end }} +{{- range $key, $val := .Values.alertmanager.templateFiles }} + {{ $key }}: {{ $val | b64enc | quote }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/service.yaml new file mode 100644 index 0000000000..858c83a4c3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/service.yaml @@ -0,0 +1,72 @@ +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if .Values.alertmanager.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager + self-monitor: {{ .Values.alertmanager.serviceMonitor.selfMonitor | quote }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.alertmanager.service.labels }} +{{ toYaml .Values.alertmanager.service.labels | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.service.annotations }} + annotations: +{{ toYaml .Values.alertmanager.service.annotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.alertmanager.service.clusterIP }} + clusterIP: {{ .Values.alertmanager.service.clusterIP }} +{{- end }} +{{- if .Values.alertmanager.service.externalIPs }} + externalIPs: +{{ toYaml .Values.alertmanager.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.alertmanager.service.loadBalancerIP }} +{{- end }} +{{- if .Values.alertmanager.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.alertmanager.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if ne .Values.alertmanager.service.type "ClusterIP" }} + externalTrafficPolicy: {{ .Values.alertmanager.service.externalTrafficPolicy }} +{{- end }} + ports: + - name: {{ .Values.alertmanager.alertmanagerSpec.portName }} + {{- if eq .Values.alertmanager.service.type "NodePort" }} + nodePort: {{ .Values.alertmanager.service.nodePort }} + {{- end }} + port: {{ .Values.alertmanager.service.port }} + targetPort: {{ .Values.alertmanager.service.targetPort }} + protocol: TCP + - name: reloader-web + {{- if semverCompare ">=1.20.0-0" $kubeTargetVersion }} + appProtocol: http + {{- end }} + port: 8080 + targetPort: reloader-web +{{- if .Values.alertmanager.service.additionalPorts }} +{{ toYaml .Values.alertmanager.service.additionalPorts | indent 2 }} +{{- end }} + selector: + app.kubernetes.io/name: alertmanager + alertmanager: {{ template "kube-prometheus-stack.alertmanager.crname" . }} +{{- if .Values.alertmanager.service.sessionAffinity }} + sessionAffinity: {{ .Values.alertmanager.service.sessionAffinity }} +{{- end }} +{{- if eq .Values.alertmanager.service.sessionAffinity "ClientIP" }} + sessionAffinityConfig: + clientIP: + timeoutSeconds: {{ .Values.alertmanager.service.sessionAffinityConfig.clientIP.timeoutSeconds }} +{{- end }} + type: "{{ .Values.alertmanager.service.type }}" +{{- if .Values.alertmanager.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.alertmanager.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.alertmanager.service.ipDualStack.ipFamilyPolicy }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/serviceaccount.yaml new file mode 100644 index 0000000000..745ced8bde --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kube-prometheus-stack.alertmanager.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager + app.kubernetes.io/name: {{ template "kube-prometheus-stack.name" . }}-alertmanager + app.kubernetes.io/component: alertmanager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.alertmanager.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.alertmanager.serviceAccount.annotations | indent 4 }} +{{- end }} +automountServiceAccountToken: {{ .Values.alertmanager.serviceAccount.automountServiceAccountToken }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2}} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/servicemonitor.yaml new file mode 100644 index 0000000000..ffba880ae1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/servicemonitor.yaml @@ -0,0 +1,84 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.serviceMonitor.selfMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- with .Values.alertmanager.serviceMonitor.additionalLabels }} +{{- toYaml . | nindent 4 }} +{{- end }} +spec: + {{- include "servicemonitor.scrapeLimits" .Values.alertmanager.serviceMonitor | nindent 2 }} + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-alertmanager + release: {{ $.Release.Name | quote }} + self-monitor: "true" + namespaceSelector: + matchNames: + - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} + endpoints: + - port: {{ .Values.alertmanager.alertmanagerSpec.portName }} + enableHttp2: {{ .Values.alertmanager.serviceMonitor.enableHttp2 }} + {{- if .Values.alertmanager.serviceMonitor.interval }} + interval: {{ .Values.alertmanager.serviceMonitor.interval }} + {{- end }} + {{- if .Values.alertmanager.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.alertmanager.serviceMonitor.proxyUrl}} + {{- end }} + {{- if .Values.alertmanager.serviceMonitor.scheme }} + scheme: {{ .Values.alertmanager.serviceMonitor.scheme }} + {{- end }} + {{- if .Values.alertmanager.serviceMonitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.alertmanager.serviceMonitor.bearerTokenFile }} + {{- end }} + {{- if .Values.alertmanager.serviceMonitor.tlsConfig }} + tlsConfig: {{- toYaml .Values.alertmanager.serviceMonitor.tlsConfig | nindent 6 }} + {{- end }} + path: "{{ trimSuffix "/" .Values.alertmanager.alertmanagerSpec.routePrefix }}/metrics" + metricRelabelings: + {{- if .Values.alertmanager.serviceMonitor.metricRelabelings }} + {{- tpl (toYaml .Values.alertmanager.serviceMonitor.metricRelabelings | nindent 6) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName }} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} + {{- if .Values.alertmanager.serviceMonitor.relabelings }} + relabelings: {{- toYaml .Values.alertmanager.serviceMonitor.relabelings | nindent 6 }} + {{- end }} + {{- range .Values.alertmanager.serviceMonitor.additionalEndpoints }} + - port: {{ .port }} + {{- if or $.Values.alertmanager.serviceMonitor.interval .interval }} + interval: {{ default $.Values.alertmanager.serviceMonitor.interval .interval }} + {{- end }} + {{- if or $.Values.alertmanager.serviceMonitor.proxyUrl .proxyUrl }} + proxyUrl: {{ default $.Values.alertmanager.serviceMonitor.proxyUrl .proxyUrl }} + {{- end }} + {{- if or $.Values.alertmanager.serviceMonitor.scheme .scheme }} + scheme: {{ default $.Values.alertmanager.serviceMonitor.scheme .scheme }} + {{- end }} + {{- if or $.Values.alertmanager.serviceMonitor.bearerTokenFile .bearerTokenFile }} + bearerTokenFile: {{ default $.Values.alertmanager.serviceMonitor.bearerTokenFile .bearerTokenFile }} + {{- end }} + {{- if or $.Values.alertmanager.serviceMonitor.tlsConfig .tlsConfig }} + tlsConfig: {{- default $.Values.alertmanager.serviceMonitor.tlsConfig .tlsConfig | toYaml | nindent 6 }} + {{- end }} + path: {{ .path }} + {{- if or $.Values.alertmanager.serviceMonitor.metricRelabelings .metricRelabelings }} + metricRelabelings: {{- tpl (default $.Values.alertmanager.serviceMonitor.metricRelabelings .metricRelabelings | toYaml | nindent 6) . }} + {{- end }} + {{- if or $.Values.alertmanager.serviceMonitor.relabelings .relabelings }} + relabelings: {{- default $.Values.alertmanager.serviceMonitor.relabelings .relabelings | toYaml | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/serviceperreplica.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/serviceperreplica.yaml new file mode 100644 index 0000000000..75a13bdf97 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/alertmanager/serviceperreplica.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.servicePerReplica.enabled }} +{{- $count := .Values.alertmanager.alertmanagerSpec.replicas | int -}} +{{- $serviceValues := .Values.alertmanager.servicePerReplica -}} +apiVersion: v1 +kind: List +metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-serviceperreplica + namespace: {{ template "kube-prometheus-stack.namespace" . }} +items: +{{- range $i, $e := until $count }} + - apiVersion: v1 + kind: Service + metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-alertmanager-{{ $i }} + namespace: {{ template "kube-prometheus-stack.namespace" $ }} + labels: + app: {{ include "kube-prometheus-stack.name" $ }}-alertmanager +{{ include "kube-prometheus-stack.labels" $ | indent 8 }} + {{- if $serviceValues.annotations }} + annotations: +{{ toYaml $serviceValues.annotations | indent 8 }} + {{- end }} + spec: + {{- if $serviceValues.clusterIP }} + clusterIP: {{ $serviceValues.clusterIP }} + {{- end }} + {{- if $serviceValues.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := $serviceValues.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} + {{- end }} + {{- if ne $serviceValues.type "ClusterIP" }} + externalTrafficPolicy: {{ $serviceValues.externalTrafficPolicy }} + {{- end }} + ports: + - name: {{ $.Values.alertmanager.alertmanagerSpec.portName }} + {{- if eq $serviceValues.type "NodePort" }} + nodePort: {{ $serviceValues.nodePort }} + {{- end }} + port: {{ $serviceValues.port }} + targetPort: {{ $serviceValues.targetPort }} + selector: + app.kubernetes.io/name: alertmanager + alertmanager: {{ template "kube-prometheus-stack.alertmanager.crname" $ }} + statefulset.kubernetes.io/pod-name: alertmanager-{{ include "kube-prometheus-stack.alertmanager.crname" $ }}-{{ $i }} + type: "{{ $serviceValues.type }}" +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/core-dns/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/core-dns/service.yaml new file mode 100644 index 0000000000..5dedc369df --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/core-dns/service.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.coreDns.enabled .Values.coreDns.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-coredns + labels: + app: {{ template "kube-prometheus-stack.name" . }}-coredns + jobLabel: coredns +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + {{- if .Values.coreDns.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.coreDns.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.coreDns.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: {{ .Values.coreDns.serviceMonitor.port }} + port: {{ .Values.coreDns.service.port }} + protocol: TCP + targetPort: {{ .Values.coreDns.service.targetPort }} + selector: + {{- if .Values.coreDns.service.selector }} +{{ toYaml .Values.coreDns.service.selector | indent 4 }} + {{- else}} + k8s-app: kube-dns + {{- end}} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/core-dns/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/core-dns/servicemonitor.yaml new file mode 100644 index 0000000000..dc15a06937 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/core-dns/servicemonitor.yaml @@ -0,0 +1,58 @@ +{{- if and .Values.coreDns.enabled .Values.coreDns.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-coredns + {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-coredns + {{- with .Values.coreDns.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.coreDns.serviceMonitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.coreDns.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.coreDns.serviceMonitor.selector }} + {{ tpl (toYaml .Values.coreDns.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-coredns + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.coreDns.serviceMonitor.port }} + {{- if .Values.coreDns.serviceMonitor.interval}} + interval: {{ .Values.coreDns.serviceMonitor.interval }} + {{- end }} + {{- if .Values.coreDns.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.coreDns.serviceMonitor.proxyUrl}} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + metricRelabelings: + {{- if .Values.coreDns.serviceMonitor.metricRelabelings }} + {{ tpl (toYaml .Values.coreDns.serviceMonitor.metricRelabelings | indent 4) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName }} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.coreDns.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.coreDns.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-api-server/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-api-server/servicemonitor.yaml new file mode 100644 index 0000000000..66e777632e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-api-server/servicemonitor.yaml @@ -0,0 +1,57 @@ +{{- if and .Values.kubeApiServer.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-apiserver + {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + namespace: default + {{- else }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-apiserver + {{- with .Values.kubeApiServer.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + {{- include "servicemonitor.scrapeLimits" .Values.kubeApiServer.serviceMonitor | nindent 2 }} + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeApiServer.serviceMonitor.interval }} + interval: {{ .Values.kubeApiServer.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubeApiServer.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeApiServer.serviceMonitor.proxyUrl }} + {{- end }} + port: https + scheme: https + metricRelabelings: + {{- if .Values.kubeApiServer.serviceMonitor.metricRelabelings }} +{{ tpl (toYaml .Values.kubeApiServer.serviceMonitor.metricRelabelings | indent 6) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.kubeApiServer.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeApiServer.serviceMonitor.relabelings | indent 6) . }} +{{- end }} + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + serverName: {{ .Values.kubeApiServer.tlsConfig.serverName }} + insecureSkipVerify: {{ .Values.kubeApiServer.tlsConfig.insecureSkipVerify }} + jobLabel: {{ .Values.kubeApiServer.serviceMonitor.jobLabel }} + namespaceSelector: + matchNames: + - default + selector: +{{ toYaml .Values.kubeApiServer.serviceMonitor.selector | indent 4 }} +{{- end}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/endpoints.yaml new file mode 100644 index 0000000000..6a6afa6412 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/endpoints.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.endpoints .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-controller-manager + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-controller-manager + k8s-app: kube-controller-manager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +subsets: + - addresses: + {{- range .Values.kubeControllerManager.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.kubeControllerManager.serviceMonitor.port }} + {{- $kubeControllerManagerDefaultInsecurePort := 10252 }} + {{- $kubeControllerManagerDefaultSecurePort := 10257 }} + port: {{ include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.port) }} + protocol: TCP +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/service.yaml new file mode 100644 index 0000000000..0a901c4acf --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/service.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-controller-manager + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-controller-manager + jobLabel: kube-controller-manager +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + {{- if .Values.kubeControllerManager.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.kubeControllerManager.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.kubeControllerManager.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: {{ .Values.kubeControllerManager.serviceMonitor.port }} + {{- $kubeControllerManagerDefaultInsecurePort := 10252 }} + {{- $kubeControllerManagerDefaultSecurePort := 10257 }} + port: {{ include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.port) }} + protocol: TCP + targetPort: {{ include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . $kubeControllerManagerDefaultInsecurePort $kubeControllerManagerDefaultSecurePort .Values.kubeControllerManager.service.targetPort) }} +{{- if .Values.kubeControllerManager.endpoints }}{{- else }} + selector: + {{- if .Values.kubeControllerManager.service.selector }} +{{ toYaml .Values.kubeControllerManager.service.selector | indent 4 }} + {{- else}} + component: kube-controller-manager + {{- end}} +{{- end }} + type: ClusterIP +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/servicemonitor.yaml new file mode 100644 index 0000000000..7ed3baa65f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-controller-manager/servicemonitor.yaml @@ -0,0 +1,69 @@ +{{- if and .Values.kubeControllerManager.enabled .Values.kubeControllerManager.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-controller-manager + {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-controller-manager + {{- with .Values.kubeControllerManager.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeControllerManager.serviceMonitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.kubeControllerManager.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.kubeControllerManager.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-controller-manager + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.kubeControllerManager.serviceMonitor.port }} + {{- if .Values.kubeControllerManager.serviceMonitor.interval }} + interval: {{ .Values.kubeControllerManager.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeControllerManager.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeControllerManager.serviceMonitor.proxyUrl}} + {{- end }} + {{- if eq (include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . false true .Values.kubeControllerManager.serviceMonitor.https )) "true" }} + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + {{- if eq (include "kube-prometheus-stack.kubeControllerManager.insecureScrape" (list . nil true .Values.kubeControllerManager.serviceMonitor.insecureSkipVerify)) "true" }} + insecureSkipVerify: true + {{- end }} + {{- if .Values.kubeControllerManager.serviceMonitor.serverName }} + serverName: {{ .Values.kubeControllerManager.serviceMonitor.serverName }} + {{- end }} + {{- end }} + metricRelabelings: + {{- if.Values.kubeControllerManager.serviceMonitor.metricRelabelings }} + {{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.metricRelabelings | indent 4) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.kubeControllerManager.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeControllerManager.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-dns/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-dns/service.yaml new file mode 100644 index 0000000000..478f419400 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-dns/service.yaml @@ -0,0 +1,32 @@ +{{- if and .Values.kubeDns.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-dns + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-dns + jobLabel: kube-dns +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + {{- if .Values.kubeDns.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.kubeDns.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.kubeDns.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: http-metrics-dnsmasq + port: {{ .Values.kubeDns.service.dnsmasq.port }} + protocol: TCP + targetPort: {{ .Values.kubeDns.service.dnsmasq.targetPort }} + - name: http-metrics-skydns + port: {{ .Values.kubeDns.service.skydns.port }} + protocol: TCP + targetPort: {{ .Values.kubeDns.service.skydns.targetPort }} + selector: + {{- if .Values.kubeDns.service.selector }} +{{ toYaml .Values.kubeDns.service.selector | indent 4 }} + {{- else}} + k8s-app: kube-dns + {{- end}} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-dns/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-dns/servicemonitor.yaml new file mode 100644 index 0000000000..9fa41b575f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-dns/servicemonitor.yaml @@ -0,0 +1,71 @@ +{{- if and .Values.kubeDns.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-dns + {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-dns + {{- with .Values.kubeDns.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeDns.serviceMonitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.kubeDns.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.kubeDns.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeDns.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-dns + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: http-metrics-dnsmasq + {{- if .Values.kubeDns.serviceMonitor.interval }} + interval: {{ .Values.kubeDns.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeDns.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeDns.serviceMonitor.proxyUrl}} + {{- end }} + metricRelabelings: + {{- if .Values.kubeDns.serviceMonitor.dnsmasqMetricRelabelings }} + {{ tpl (toYaml .Values.kubeDns.serviceMonitor.dnsmasqMetricRelabelings | indent 4) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.kubeDns.serviceMonitor.dnsmasqRelabelings }} + relabelings: +{{ toYaml .Values.kubeDns.serviceMonitor.dnsmasqRelabelings | indent 4 }} +{{- end }} + - port: http-metrics-skydns + {{- if .Values.kubeDns.serviceMonitor.interval }} + interval: {{ .Values.kubeDns.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- if .Values.kubeDns.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubeDns.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubeDns.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeDns.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/endpoints.yaml new file mode 100644 index 0000000000..e366447577 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/endpoints.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.endpoints .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-etcd + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-etcd + k8s-app: etcd-server +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +subsets: + - addresses: + {{- range .Values.kubeEtcd.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.kubeEtcd.serviceMonitor.port }} + port: {{ .Values.kubeEtcd.service.port }} + protocol: TCP +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/service.yaml new file mode 100644 index 0000000000..a62059aa4e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/service.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-etcd + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-etcd + jobLabel: kube-etcd +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + {{- if .Values.kubeEtcd.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.kubeEtcd.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.kubeEtcd.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: {{ .Values.kubeEtcd.serviceMonitor.port }} + port: {{ .Values.kubeEtcd.service.port }} + protocol: TCP + targetPort: {{ .Values.kubeEtcd.service.targetPort }} +{{- if .Values.kubeEtcd.endpoints }}{{- else }} + selector: + {{- if .Values.kubeEtcd.service.selector }} +{{ toYaml .Values.kubeEtcd.service.selector | indent 4 }} + {{- else}} + component: etcd + {{- end}} +{{- end }} + type: ClusterIP +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/servicemonitor.yaml new file mode 100644 index 0000000000..26fdbdbed3 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-etcd/servicemonitor.yaml @@ -0,0 +1,75 @@ +{{- if and .Values.kubeEtcd.enabled .Values.kubeEtcd.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-etcd + {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-etcd + {{- with .Values.kubeEtcd.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeEtcd.serviceMonitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.kubeEtcd.serviceMonitor | nindent 4 }} + selector: + {{- if .Values.kubeEtcd.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-etcd + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.kubeEtcd.serviceMonitor.port }} + {{- if .Values.kubeEtcd.serviceMonitor.interval }} + interval: {{ .Values.kubeEtcd.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeEtcd.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeEtcd.serviceMonitor.proxyUrl}} + {{- end }} + {{- if eq .Values.kubeEtcd.serviceMonitor.scheme "https" }} + scheme: https + tlsConfig: + {{- if .Values.kubeEtcd.serviceMonitor.serverName }} + serverName: {{ .Values.kubeEtcd.serviceMonitor.serverName }} + {{- end }} + {{- if .Values.kubeEtcd.serviceMonitor.caFile }} + caFile: {{ .Values.kubeEtcd.serviceMonitor.caFile }} + {{- end }} + {{- if .Values.kubeEtcd.serviceMonitor.certFile }} + certFile: {{ .Values.kubeEtcd.serviceMonitor.certFile }} + {{- end }} + {{- if .Values.kubeEtcd.serviceMonitor.keyFile }} + keyFile: {{ .Values.kubeEtcd.serviceMonitor.keyFile }} + {{- end}} + insecureSkipVerify: {{ .Values.kubeEtcd.serviceMonitor.insecureSkipVerify }} + {{- end }} + metricRelabelings: + {{- if .Values.kubeEtcd.serviceMonitor.metricRelabelings }} + {{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.metricRelabelings | indent 4) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.kubeEtcd.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeEtcd.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/endpoints.yaml new file mode 100644 index 0000000000..8613e62425 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/endpoints.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.endpoints .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-proxy + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-proxy + k8s-app: kube-proxy +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +subsets: + - addresses: + {{- range .Values.kubeProxy.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.kubeProxy.serviceMonitor.port }} + port: {{ .Values.kubeProxy.service.port }} + protocol: TCP +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/service.yaml new file mode 100644 index 0000000000..672f5492b8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/service.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-proxy + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-proxy + jobLabel: kube-proxy +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + {{- if .Values.kubeProxy.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.kubeProxy.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.kubeProxy.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: {{ .Values.kubeProxy.serviceMonitor.port }} + port: {{ .Values.kubeProxy.service.port }} + protocol: TCP + targetPort: {{ .Values.kubeProxy.service.targetPort }} +{{- if .Values.kubeProxy.endpoints }}{{- else }} + selector: + {{- if .Values.kubeProxy.service.selector }} +{{ toYaml .Values.kubeProxy.service.selector | indent 4 }} + {{- else}} + k8s-app: kube-proxy + {{- end}} +{{- end }} + type: ClusterIP +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/servicemonitor.yaml new file mode 100644 index 0000000000..24b0ab2001 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-proxy/servicemonitor.yaml @@ -0,0 +1,63 @@ +{{- if and .Values.kubeProxy.enabled .Values.kubeProxy.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-proxy + {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-proxy + {{- with .Values.kubeProxy.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeProxy.serviceMonitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.kubeProxy.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.kubeProxy.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeProxy.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-proxy + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.kubeProxy.serviceMonitor.port }} + {{- if .Values.kubeProxy.serviceMonitor.interval }} + interval: {{ .Values.kubeProxy.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeProxy.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeProxy.serviceMonitor.proxyUrl}} + {{- end }} + {{- if .Values.kubeProxy.serviceMonitor.https }} + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + {{- end}} + metricRelabelings: + {{- if .Values.kubeProxy.serviceMonitor.metricRelabelings }} + {{ tpl (toYaml .Values.kubeProxy.serviceMonitor.metricRelabelings | indent 4) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.kubeProxy.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeProxy.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/endpoints.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/endpoints.yaml new file mode 100644 index 0000000000..6236b42f10 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/endpoints.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.endpoints .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-scheduler + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-scheduler + k8s-app: kube-scheduler +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +subsets: + - addresses: + {{- range .Values.kubeScheduler.endpoints }} + - ip: {{ . }} + {{- end }} + ports: + - name: {{ .Values.kubeScheduler.serviceMonitor.port }} + {{- $kubeSchedulerDefaultInsecurePort := 10251 }} + {{- $kubeSchedulerDefaultSecurePort := 10259 }} + port: {{ include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.port) }} + protocol: TCP +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/service.yaml new file mode 100644 index 0000000000..8663d79f0d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/service.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.service.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-scheduler + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-scheduler + jobLabel: kube-scheduler +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: kube-system +spec: + clusterIP: None + {{- if .Values.kubeScheduler.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.kubeScheduler.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.kubeScheduler.service.ipDualStack.ipFamilyPolicy }} + {{- end }} + ports: + - name: {{ .Values.kubeScheduler.serviceMonitor.port }} + {{- $kubeSchedulerDefaultInsecurePort := 10251 }} + {{- $kubeSchedulerDefaultSecurePort := 10259 }} + port: {{ include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.port) }} + protocol: TCP + targetPort: {{ include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . $kubeSchedulerDefaultInsecurePort $kubeSchedulerDefaultSecurePort .Values.kubeScheduler.service.targetPort) }} +{{- if .Values.kubeScheduler.endpoints }}{{- else }} + selector: + {{- if .Values.kubeScheduler.service.selector }} +{{ toYaml .Values.kubeScheduler.service.selector | indent 4 }} + {{- else}} + component: kube-scheduler + {{- end}} +{{- end }} + type: ClusterIP +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/servicemonitor.yaml new file mode 100644 index 0000000000..b17c4f1d47 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-scheduler/servicemonitor.yaml @@ -0,0 +1,69 @@ +{{- if and .Values.kubeScheduler.enabled .Values.kubeScheduler.serviceMonitor.enabled .Values.kubernetesServiceMonitors.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kube-scheduler + {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + namespace: kube-system + {{- else }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-scheduler + {{- with .Values.kubeScheduler.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + jobLabel: {{ .Values.kubeScheduler.serviceMonitor.jobLabel }} + {{- include "servicemonitor.scrapeLimits" .Values.kubeScheduler.serviceMonitor | nindent 2 }} + selector: + {{- if .Values.kubeScheduler.serviceMonitor.selector }} + {{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.selector | nindent 4) . }} + {{- else }} + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-kube-scheduler + release: {{ $.Release.Name | quote }} + {{- end }} + namespaceSelector: + matchNames: + - "kube-system" + endpoints: + - port: {{ .Values.kubeScheduler.serviceMonitor.port }} + {{- if .Values.kubeScheduler.serviceMonitor.interval }} + interval: {{ .Values.kubeScheduler.serviceMonitor.interval }} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if .Values.kubeScheduler.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubeScheduler.serviceMonitor.proxyUrl}} + {{- end }} + {{- if eq (include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . false true .Values.kubeScheduler.serviceMonitor.https )) "true" }} + scheme: https + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + {{- if eq (include "kube-prometheus-stack.kubeScheduler.insecureScrape" (list . nil true .Values.kubeScheduler.serviceMonitor.insecureSkipVerify)) "true" }} + insecureSkipVerify: true + {{- end }} + {{- if .Values.kubeScheduler.serviceMonitor.serverName }} + serverName: {{ .Values.kubeScheduler.serviceMonitor.serverName }} + {{- end}} + {{- end}} + metricRelabelings: + {{- if .Values.kubeScheduler.serviceMonitor.metricRelabelings }} + {{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.metricRelabelings | indent 4) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.kubeScheduler.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubeScheduler.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-state-metrics/validate.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-state-metrics/validate.yaml new file mode 100644 index 0000000000..9211b3d771 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kube-state-metrics/validate.yaml @@ -0,0 +1,7 @@ +{{- if .Values.kubeStateMetrics.enabled }} +{{- if not (kindIs "invalid" .Values.kubeStateMetrics.serviceMonitor) }} +{{- if .Values.kubeStateMetrics.serviceMonitor.namespaceOverride }} +{{- fail "kubeStateMetrics.serviceMonitor.namespaceOverride was removed. Please use kube-state-metrics.namespaceOverride instead." }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kubelet/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kubelet/servicemonitor.yaml new file mode 100644 index 0000000000..f570fbfdbc --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/kubelet/servicemonitor.yaml @@ -0,0 +1,246 @@ +{{- if (and (not .Values.kubelet.enabled) .Values.hardenedKubelet.enabled) }} +{{ required "Cannot set .Values.hardenedKubelet.enabled=true when .Values.kubelet.enabled=false" "" }} +{{- end }} +{{- if (and .Values.kubelet.enabled .Values.kubernetesServiceMonitors.enabled (not .Values.hardenedKubelet.enabled) (not .Values.k3sServer.enabled)) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-kubelet + {{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + namespace: {{ .Values.kubelet.namespace }} + {{- else }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-kubelet + {{- with .Values.kubelet.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + {{- include "servicemonitor.scrapeLimits" .Values.kubelet.serviceMonitor | nindent 2 }} + {{- with .Values.kubelet.serviceMonitor.attachMetadata }} + attachMetadata: + {{- toYaml . | nindent 4 }} + {{- end }} + endpoints: + {{- if .Values.kubelet.serviceMonitor.https }} + - port: https-metrics + scheme: https + {{- if .Values.kubelet.serviceMonitor.interval }} + interval: {{ .Values.kubelet.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} + {{- end }} + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecureSkipVerify: true + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} + honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} + metricRelabelings: + {{- if .Values.kubelet.serviceMonitor.metricRelabelings }} + {{- tpl (toYaml .Values.kubelet.serviceMonitor.metricRelabelings | nindent 6) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.kubelet.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.cAdvisor }} + - port: https-metrics + scheme: https + path: /metrics/cadvisor + {{- if .Values.kubelet.serviceMonitor.interval }} + interval: {{ .Values.kubelet.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} + {{- end }} + honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} + honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecureSkipVerify: true + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- if .Values.kubelet.serviceMonitor.cAdvisorMetricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.cAdvisorMetricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.cAdvisorRelabelings }} + relabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.cAdvisorRelabelings | indent 4) . }} +{{- end }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.probes }} + - port: https-metrics + scheme: https + path: /metrics/probes + {{- if .Values.kubelet.serviceMonitor.interval }} + interval: {{ .Values.kubelet.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} + {{- end }} + honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} + honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecureSkipVerify: true + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- if .Values.kubelet.serviceMonitor.probesMetricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.probesMetricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.probesRelabelings }} + relabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.probesRelabelings | indent 4) . }} +{{- end }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.resource }} + - port: https-metrics + scheme: https + path: {{ include "kubelet.serviceMonitor.resourcePath" . }} + {{- if .Values.kubelet.serviceMonitor.interval }} + interval: {{ .Values.kubelet.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} + {{- end }} + honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} + honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecureSkipVerify: true + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +{{- if .Values.kubelet.serviceMonitor.resourceMetricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.resourceMetricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.resourceRelabelings }} + relabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.resourceRelabelings | indent 4) . }} +{{- end }} +{{- end }} + {{- else }} + - port: http-metrics + {{- if .Values.kubelet.serviceMonitor.interval }} + interval: {{ .Values.kubelet.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} + {{- end }} + honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} + honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} +{{- if .Values.kubelet.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.relabelings }} + relabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.relabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.cAdvisor }} + - port: http-metrics + path: /metrics/cadvisor + {{- if .Values.kubelet.serviceMonitor.interval }} + interval: {{ .Values.kubelet.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} + {{- end }} + honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} + honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} +{{- if .Values.kubelet.serviceMonitor.cAdvisorMetricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.cAdvisorMetricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.cAdvisorRelabelings }} + relabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.cAdvisorRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.probes }} + - port: http-metrics + path: /metrics/probes + {{- if .Values.kubelet.serviceMonitor.interval }} + interval: {{ .Values.kubelet.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} + {{- end }} + honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} + honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} +{{- if .Values.kubelet.serviceMonitor.probesMetricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.probesMetricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.probesRelabelings }} + relabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.probesRelabelings | indent 4) . }} +{{- end }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.resource }} + - port: http-metrics + path: {{ include "kubelet.serviceMonitor.resourcePath" . }} + {{- if .Values.kubelet.serviceMonitor.interval }} + interval: {{ .Values.kubelet.serviceMonitor.interval }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.kubelet.serviceMonitor.proxyUrl }} + {{- end }} + {{- if .Values.kubelet.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.kubelet.serviceMonitor.scrapeTimeout }} + {{- end }} + honorLabels: {{ .Values.kubelet.serviceMonitor.honorLabels }} + honorTimestamps: {{ .Values.kubelet.serviceMonitor.honorTimestamps }} +{{- if .Values.kubelet.serviceMonitor.resourceMetricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.resourceMetricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.kubelet.serviceMonitor.resourceRelabelings }} + relabelings: +{{ tpl (toYaml .Values.kubelet.serviceMonitor.resourceRelabelings | indent 4) . }} +{{- end }} +{{- end }} +{{- end }} + {{- end }} + jobLabel: k8s-app + namespaceSelector: + matchNames: + - {{ .Values.kubelet.namespace }} + selector: + matchLabels: + app.kubernetes.io/name: kubelet + k8s-app: kubelet +{{- end}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/node-exporter/validate.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/node-exporter/validate.yaml new file mode 100644 index 0000000000..bdc73d6165 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/exporters/node-exporter/validate.yaml @@ -0,0 +1,3 @@ +{{- if (and (not .Values.nodeExporter.enabled) .Values.hardenedNodeExporter.enabled) }} +{{ required "Cannot set .Values.hardenedNodeExporter.enabled=true when .Values.nodeExporter.enabled=false" "" }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/extra-objects.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/extra-objects.yaml new file mode 100644 index 0000000000..567f7bf329 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/extra-objects.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraManifests }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/configmap-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/configmap-dashboards.yaml new file mode 100644 index 0000000000..e719009ffe --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/configmap-dashboards.yaml @@ -0,0 +1,24 @@ +{{- if or (and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled) .Values.grafana.forceDeployDashboards }} +{{- $files := .Files.Glob "dashboards-1.14/*.json" }} +{{- if $files }} +apiVersion: v1 +kind: ConfigMapList +items: +{{- range $path, $fileContents := $files }} +{{- $dashboardName := regexReplaceAll "(^.*/)(.*)\\.json$" $path "${2}" }} +- apiVersion: v1 + kind: ConfigMap + metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) $dashboardName | trunc 63 | trimSuffix "-" }} + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 6 }} + data: + {{ $dashboardName }}.json: {{ $.Files.Get $path | toJson }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/configmaps-datasources.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/configmaps-datasources.yaml new file mode 100644 index 0000000000..135bad440d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/configmaps-datasources.yaml @@ -0,0 +1,81 @@ +{{- if or (and .Values.grafana.enabled .Values.grafana.sidecar.datasources.enabled) .Values.grafana.forceDeployDatasources }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-grafana-datasource + namespace: {{ default .Values.grafana.sidecar.datasources.searchNamespace (include "kube-prometheus-stack.namespace" .) }} +{{- if .Values.grafana.sidecar.datasources.annotations }} + annotations: + {{- toYaml .Values.grafana.sidecar.datasources.annotations | nindent 4 }} +{{- end }} + labels: + {{ $.Values.grafana.sidecar.datasources.label }}: {{ $.Values.grafana.sidecar.datasources.labelValue | quote }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + datasource.yaml: |- + apiVersion: 1 +{{- if .Values.grafana.deleteDatasources }} + deleteDatasources: +{{ tpl (toYaml .Values.grafana.deleteDatasources | indent 6) . }} +{{- end }} + datasources: +{{- $scrapeInterval := .Values.grafana.sidecar.datasources.defaultDatasourceScrapeInterval | default .Values.prometheus.prometheusSpec.scrapeInterval | default "30s" }} +{{- if .Values.grafana.sidecar.datasources.defaultDatasourceEnabled }} + - name: "{{ .Values.grafana.sidecar.datasources.name }}" + type: prometheus + uid: {{ .Values.grafana.sidecar.datasources.uid }} + {{- if .Values.grafana.sidecar.datasources.url }} + url: {{ .Values.grafana.sidecar.datasources.url }} + {{- else }} + url: http://{{ template "kube-prometheus-stack.fullname" . }}-prometheus.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.prometheus.service.port }}/{{ trimPrefix "/" .Values.prometheus.prometheusSpec.routePrefix }} + {{- end }} + access: proxy + isDefault: {{ .Values.grafana.sidecar.datasources.isDefaultDatasource }} + jsonData: + httpMethod: {{ .Values.grafana.sidecar.datasources.httpMethod }} + timeInterval: {{ $scrapeInterval }} + {{- if .Values.grafana.sidecar.datasources.timeout }} + timeout: {{ .Values.grafana.sidecar.datasources.timeout }} + {{- end }} +{{- if .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations }} + exemplarTraceIdDestinations: + - datasourceUid: {{ .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.datasourceUid }} + name: {{ .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.traceIdLabelName }} +{{- end }} +{{- if .Values.grafana.sidecar.datasources.createPrometheusReplicasDatasources }} +{{- range until (int .Values.prometheus.prometheusSpec.replicas) }} + - name: "{{ $.Values.grafana.sidecar.datasources.name }}-{{ . }}" + type: prometheus + uid: {{ $.Values.grafana.sidecar.datasources.uid }}-replica-{{ . }} + url: http://prometheus-{{ template "kube-prometheus-stack.prometheus.crname" $ }}-{{ . }}.prometheus-operated:9090/{{ trimPrefix "/" $.Values.prometheus.prometheusSpec.routePrefix }} + access: proxy + isDefault: false + jsonData: + timeInterval: {{ $scrapeInterval }} +{{- if $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations }} + exemplarTraceIdDestinations: + - datasourceUid: {{ $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.datasourceUid }} + name: {{ $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.traceIdLabelName }} +{{- end }} +{{- end }} +{{- end }} +{{- if .Values.grafana.sidecar.datasources.alertmanager.enabled }} + - name: "{{ .Values.grafana.sidecar.datasources.alertmanager.name }}" + type: alertmanager + uid: {{ .Values.grafana.sidecar.datasources.alertmanager.uid }} + {{- if .Values.grafana.sidecar.datasources.alertmanager.url }} + url: {{ .Values.grafana.sidecar.datasources.alertmanager.url }} + {{- else }} + url: http://{{ template "kube-prometheus-stack.fullname" . }}-alertmanager.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.alertmanager.service.port }}/{{ trimPrefix "/" .Values.alertmanager.alertmanagerSpec.routePrefix }} + {{- end }} + access: proxy + jsonData: + handleGrafanaManagedAlerts: {{ .Values.grafana.sidecar.datasources.alertmanager.handleGrafanaManagedAlerts }} + implementation: {{ .Values.grafana.sidecar.datasources.alertmanager.implementation }} +{{- end }} +{{- end }} +{{- if .Values.grafana.additionalDataSources }} +{{ tpl (toYaml .Values.grafana.additionalDataSources | indent 4) . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/alertmanager-overview.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/alertmanager-overview.yaml new file mode 100644 index 0000000000..216467bdf7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/alertmanager-overview.yaml @@ -0,0 +1,616 @@ +{{- /* +Generated from 'alertmanager-overview' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +{{- if and .Values.alertmanager.enabled .Values.alertmanager.serviceMonitor.selfMonitor }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "alertmanager-overview" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + alertmanager-overview.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 1, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "30s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "current set of alerts stored in the Alertmanager", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 2, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(alertmanager_alerts{namespace=~\"$namespace\",service=~\"$service\"}) by (namespace,service,instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Alerts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "rate of successful and invalid alerts received by the Alertmanager", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(alertmanager_alerts_received_total{namespace=~\"$namespace\",service=~\"$service\"}[$__rate_interval])) by (namespace,service,instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Received", + "refId": "A" + }, + { + "expr": "sum(rate(alertmanager_alerts_invalid_total{namespace=~\"$namespace\",service=~\"$service\"}[$__rate_interval])) by (namespace,service,instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Invalid", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Alerts receive rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Alerts", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "rate of successful and invalid notifications sent by the Alertmanager", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "integration", + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(alertmanager_notifications_total{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (integration,namespace,service,instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Total", + "refId": "A" + }, + { + "expr": "sum(rate(alertmanager_notifications_failed_total{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (integration,namespace,service,instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Failed", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "$integration: Notifications Send Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "latency of notifications sent by the Alertmanager", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 5, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "integration", + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99,\n sum(rate(alertmanager_notification_latency_seconds_bucket{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (le,namespace,service,instance)\n) \n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} 99th Percentile", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.50,\n sum(rate(alertmanager_notification_latency_seconds_bucket{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (le,namespace,service,instance)\n) \n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Median", + "refId": "B" + }, + { + "expr": "sum(rate(alertmanager_notification_latency_seconds_sum{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (namespace,service,instance)\n/\nsum(rate(alertmanager_notification_latency_seconds_count{namespace=~\"$namespace\",service=~\"$service\", integration=\"$integration\"}[$__rate_interval])) by (namespace,service,instance)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Average", + "refId": "C" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "$integration: Notification Duration", + "tooltip": { + "shared": true, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Notifications", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "alertmanager-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(alertmanager_alerts, namespace)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "service", + "multi": false, + "name": "service", + "options": [ + + ], + "query": "label_values(alertmanager_alerts, service)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "all", + "value": "$__all" + }, + "datasource": "$datasource", + "hide": 2, + "includeAll": true, + "label": null, + "multi": false, + "name": "integration", + "options": [ + + ], + "query": "label_values(alertmanager_notifications_total{integration=~\".*\"}, integration)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Alertmanager / Overview", + "uid": "alertmanager-overview", + "version": 0 + } +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/apiserver.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/apiserver.yaml new file mode 100644 index 0000000000..c05d6ceebb --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/apiserver.yaml @@ -0,0 +1,1772 @@ +{{- /* +Generated from 'apiserver' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.kubeApiServer.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "apiserver" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + apiserver.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "panels": [ + { + "content": "The SLO (service level objective) and other metrics displayed on this dashboard are for informational purposes only.", + "datasource": null, + "description": "The SLO (service level objective) and other metrics displayed on this dashboard are for informational purposes only.", + "gridPos": { + "h": 2, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "mode": "markdown", + "span": 12, + "title": "Notice", + "type": "text" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "decimals": 3, + "description": "How many percent of requests (both read and write) in 30 days have been answered successfully and fast enough?", + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + + }, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "rightSide": true + }, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 4, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "apiserver_request:availability30d{verb=\"all\", cluster=\"$cluster\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "Availability (30d) > 99.000%", + "tooltip": { + "shared": false + }, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": 3, + "description": "How much error budget is left looking at our 0.990% availability guarantees?", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 8, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "100 * (apiserver_request:availability30d{verb=\"all\", cluster=\"$cluster\"} - 0.990000)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "errorbudget", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "ErrorBudget (30d) > 99.000%", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "decimals": 3, + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": 3, + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "decimals": 3, + "description": "How many percent of read requests (LIST,GET) in 30 days have been answered successfully and fast enough?", + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + + }, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "rightSide": true + }, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "apiserver_request:availability30d{verb=\"read\", cluster=\"$cluster\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "Read Availability (30d)", + "tooltip": { + "shared": false + }, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "How many read requests (LIST,GET) per second do the apiservers get by code?", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "alias": "/2../i", + "color": "#56A64B" + }, + { + "alias": "/3../i", + "color": "#F2CC0C" + }, + { + "alias": "/4../i", + "color": "#3274D9" + }, + { + "alias": "/5../i", + "color": "#E02F44" + } + ], + "spaceLength": 10, + "span": 3, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (code) (code_resource:apiserver_request_total:rate5m{verb=\"read\", cluster=\"$cluster\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}} code {{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Read SLI - Requests", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "How many percent of read requests (LIST,GET) per second are returned with errors (5xx)?", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"read\",code=~\"5..\", cluster=\"$cluster\"}) / sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"read\", cluster=\"$cluster\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}} resource {{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Read SLI - Errors", + "tooltip": { + "shared": false, + "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": null, + "min": 0, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "How many seconds is the 99th percentile for reading (LIST|GET) a given resource?", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "cluster_quantile:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds:histogram_quantile{verb=\"read\", cluster=\"$cluster\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}} resource {{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Read SLI - Duration", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "decimals": 3, + "description": "How many percent of write requests (POST|PUT|PATCH|DELETE) in 30 days have been answered successfully and fast enough?", + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + + }, + "id": 9, + "interval": "1m", + "legend": { + "alignAsTable": true, + "rightSide": true + }, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "apiserver_request:availability30d{verb=\"write\", cluster=\"$cluster\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "Write Availability (30d)", + "tooltip": { + "shared": false + }, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "How many write requests (POST|PUT|PATCH|DELETE) per second do the apiservers get by code?", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "alias": "/2../i", + "color": "#56A64B" + }, + { + "alias": "/3../i", + "color": "#F2CC0C" + }, + { + "alias": "/4../i", + "color": "#3274D9" + }, + { + "alias": "/5../i", + "color": "#E02F44" + } + ], + "spaceLength": 10, + "span": 3, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (code) (code_resource:apiserver_request_total:rate5m{verb=\"write\", cluster=\"$cluster\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}} code {{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Write SLI - Requests", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "How many percent of write requests (POST|PUT|PATCH|DELETE) per second are returned with errors (5xx)?", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 11, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"write\",code=~\"5..\", cluster=\"$cluster\"}) / sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\"write\", cluster=\"$cluster\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}} resource {{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Write SLI - Errors", + "tooltip": { + "shared": false, + "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": null, + "min": 0, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "How many seconds is the 99th percentile for writing (POST|PUT|PATCH|DELETE) a given resource?", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 12, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "cluster_quantile:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds:histogram_quantile{verb=\"write\", cluster=\"$cluster\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}} resource {{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Write SLI - Duration", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 13, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(workqueue_adds_total{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Work Queue Add Rate", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 14, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(workqueue_depth{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Work Queue Depth", + "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": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 15, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"apiserver\", instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])) by (instance, name, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Work Queue Latency", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 16, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": false, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 17, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU usage", + "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": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 18, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_goroutines{job=\"apiserver\",instance=~\"$instance\", cluster=\"$cluster\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Goroutines", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"apiserver\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(up{job=\"apiserver\", cluster=\"$cluster\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / API server", + "uid": "09ec8aa1e996d6ffcd6817bbaff4db1b", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/cluster-total.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/cluster-total.yaml new file mode 100644 index 0000000000..cf8e00540c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/cluster-total.yaml @@ -0,0 +1,1882 @@ +{{- /* +Generated from 'cluster-total' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "cluster-total" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + cluster-total.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "panels": [ + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Current Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Received", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Transmitted", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "columns": [ + { + "text": "Time", + "value": "Time" + }, + { + "text": "Value #A", + "value": "Value #A" + }, + { + "text": "Value #B", + "value": "Value #B" + }, + { + "text": "Value #C", + "value": "Value #C" + }, + { + "text": "Value #D", + "value": "Value #D" + }, + { + "text": "Value #E", + "value": "Value #E" + }, + { + "text": "Value #F", + "value": "Value #F" + }, + { + "text": "Value #G", + "value": "Value #G" + }, + { + "text": "Value #H", + "value": "Value #H" + }, + { + "text": "namespace", + "value": "namespace" + } + ], + "datasource": "$datasource", + "fill": 1, + "fontSize": "90%", + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 5, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null as zero", + "renderer": "flot", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": false + }, + "spaceLength": 10, + "span": 24, + "styles": [ + { + "alias": "Time", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Time", + "thresholds": [ + + ], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Current Bandwidth Received", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Current Bandwidth Transmitted", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Average Bandwidth Received", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Average Bandwidth Transmitted", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Rate of Received Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Received Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #G", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #H", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Namespace", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTooltip": "Drill down", + "linkUrl": "d/8b7a8b326d7a6f1f04244066368c67af/kubernetes-networking-namespace-pods?orgId=1&refresh=30s&var-namespace=$__cell", + "pattern": "namespace", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "G", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "H", + "step": 10 + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Status", + "type": "table" + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 6, + "panels": [ + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 11 + }, + "id": 7, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Rate of Bytes Received", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 11 + }, + "id": 8, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Rate of Bytes Transmitted", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Average Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 11 + }, + "id": 9, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth History", + "titleSize": "h6", + "type": "row" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 11, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 12, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 13, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 40 + }, + "id": 14, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Packets", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 15, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 50 + }, + "id": 16, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 59 + }, + "id": 17, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\".+\"}[$interval:$resolution])) by (namespace))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 59 + }, + "id": 18, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [ + { + "targetBlank": true, + "title": "What is TCP Retransmit?", + "url": "https://accedian.com/enterprises/blog/network-packet-loss-retransmissions-and-duplicate-acknowledgements/" + } + ], + "minSpan": 24, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(rate(node_netstat_Tcp_RetransSegs{cluster=\"$cluster\"}[$interval:$resolution]) / rate(node_netstat_Tcp_OutSegs{cluster=\"$cluster\"}[$interval:$resolution])) by (instance))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of TCP Retransmits out of all sent segments", + "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": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 59 + }, + "id": 19, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [ + { + "targetBlank": true, + "title": "Why monitor SYN retransmits?", + "url": "https://github.com/prometheus/node_exporter/issues/1023#issuecomment-408128365" + } + ], + "minSpan": 24, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(rate(node_netstat_TcpExt_TCPSynRetrans{cluster=\"$cluster\"}[$interval:$resolution]) / rate(node_netstat_Tcp_RetransSegs{cluster=\"$cluster\"}[$interval:$resolution])) by (instance))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of TCP SYN Retransmits out of all retransmits", + "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": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Errors", + "titleSize": "h6", + "type": "row" + } + ], + "refresh": "10s", + "rows": [ + + ], + "schemaVersion": 18, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "resolution", + "options": [ + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": true, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + } + ], + "query": "30s,5m,1h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 2, + "includeAll": false, + "label": null, + "multi": false, + "name": "interval", + "options": [ + { + "selected": true, + "text": "4h", + "value": "4h" + } + ], + "query": "4h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "useTags": false + }, + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 0, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Networking / Cluster", + "uid": "ff635a025bcfea7bc3dd4f508990a3e9", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/controller-manager.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/controller-manager.yaml new file mode 100644 index 0000000000..507d47555d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/controller-manager.yaml @@ -0,0 +1,1196 @@ +{{- /* +Generated from 'controller-manager' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +{{- if (include "exporter.kubeControllerManager.enabled" .)}} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "controller-manager" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + controller-manager.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + + }, + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "rightSide": true + }, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + {{- if .Values.k3sServer.enabled }} + "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", metrics_path=\"/metrics\"})", + {{- else }} + "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\"})", + {{- end }} + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "Up", + "tooltip": { + "shared": false + }, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "min" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(workqueue_adds_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Work Queue Add Rate", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(workqueue_depth{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Work Queue Depth", + "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": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, name, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} {{`{{`}}name{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Work Queue Latency", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(rest_client_requests_total{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "2xx", + "refId": "A" + }, + { + "expr": "sum(rate(rest_client_requests_total{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "3xx", + "refId": "B" + }, + { + "expr": "sum(rate(rest_client_requests_total{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "4xx", + "refId": "C" + }, + { + "expr": "sum(rate(rest_client_requests_total{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "5xx", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Kube API Request Rate", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 8, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\", verb=\"POST\"}[$__rate_interval])) by (verb, url, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Post Request Latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, url, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Get Request Latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 9, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": false, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU usage", + "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": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 11, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_goroutines{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Goroutines", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeControllerManager.jobName" . }}\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Controller Manager", + "uid": "72e0e05bef5099e5f049b05fdc429ed4", + "version": 0 + } +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/etcd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/etcd.yaml new file mode 100644 index 0000000000..0eeedc6299 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/etcd.yaml @@ -0,0 +1,1229 @@ +{{- /* +Generated from 'etcd' from https://github.com/etcd-io/etcd.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +{{- if (include "exporter.kubeEtcd.enabled" .)}} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "etcd" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + etcd.json: |- + { + "annotations": { + "list": [] + }, + "description": "etcd sample Grafana dashboard with Prometheus", + "editable": true, + "gnetId": null, + "hideControls": false, + "links": [], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "$datasource", + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "id": 28, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [ + { + "expr": "sum(etcd_server_has_leader{job=\"$cluster\"})", + "intervalFactor": 2, + "legendFormat": "", + "metric": "etcd_server_has_leader", + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Up", + "type": "singlestat", + "valueFontSize": "200%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fill": 0, + "id": 23, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 5, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(grpc_server_started_total{job=\"$cluster\",grpc_type=\"unary\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "RPC Rate", + "metric": "grpc_server_started_total", + "refId": "A", + "step": 2 + }, + { + "expr": "sum(rate(grpc_server_handled_total{job=\"$cluster\",grpc_type=\"unary\",grpc_code=~\"Unknown|FailedPrecondition|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "RPC Failed Rate", + "metric": "grpc_server_handled_total", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "RPC Rate", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fill": 0, + "id": 41, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(grpc_server_started_total{job=\"$cluster\",grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"}) - sum(grpc_server_handled_total{job=\"$cluster\",grpc_service=\"etcdserverpb.Watch\",grpc_type=\"bidi_stream\"})", + "intervalFactor": 2, + "legendFormat": "Watch Streams", + "metric": "grpc_server_handled_total", + "refId": "A", + "step": 4 + }, + { + "expr": "sum(grpc_server_started_total{job=\"$cluster\",grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"}) - sum(grpc_server_handled_total{job=\"$cluster\",grpc_service=\"etcdserverpb.Lease\",grpc_type=\"bidi_stream\"})", + "intervalFactor": 2, + "legendFormat": "Lease Streams", + "metric": "grpc_server_handled_total", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Active Streams", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "showTitle": false, + "title": "Row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "decimals": null, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "etcd_mvcc_db_total_size_in_bytes{job=\"$cluster\"}", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} DB Size", + "metric": "", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "DB Size", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 4, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_wal_fsync_duration_seconds_bucket{job=\"$cluster\"}[$__rate_interval])) by (instance, le))", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} WAL fsync", + "metric": "etcd_disk_wal_fsync_duration_seconds_bucket", + "refId": "A", + "step": 4 + }, + { + "expr": "histogram_quantile(0.99, sum(rate(etcd_disk_backend_commit_duration_seconds_bucket{job=\"$cluster\"}[$__rate_interval])) by (instance, le))", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} DB fsync", + "metric": "etcd_disk_backend_commit_duration_seconds_bucket", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Disk Sync Duration", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fill": 0, + "id": 29, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{job=\"$cluster\"}", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Resident Memory", + "metric": "process_resident_memory_bytes", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "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 + } + ] + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fill": 5, + "id": 22, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 3, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(etcd_network_client_grpc_received_bytes_total{job=\"$cluster\"}[$__rate_interval])", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Client Traffic In", + "metric": "etcd_network_client_grpc_received_bytes_total", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Client Traffic In", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fill": 5, + "id": 21, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 3, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(etcd_network_client_grpc_sent_bytes_total{job=\"$cluster\"}[$__rate_interval])", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Client Traffic Out", + "metric": "etcd_network_client_grpc_sent_bytes_total", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Client Traffic Out", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fill": 0, + "id": 20, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(etcd_network_peer_received_bytes_total{job=\"$cluster\"}[$__rate_interval])) by (instance)", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Peer Traffic In", + "metric": "etcd_network_peer_received_bytes_total", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Peer Traffic In", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "decimals": null, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(etcd_network_peer_sent_bytes_total{job=\"$cluster\"}[$__rate_interval])) by (instance)", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Peer Traffic Out", + "metric": "etcd_network_peer_sent_bytes_total", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Peer Traffic Out", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fill": 0, + "id": 40, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(etcd_server_proposals_failed_total{job=\"$cluster\"}[$__rate_interval]))", + "intervalFactor": 2, + "legendFormat": "Proposal Failure Rate", + "metric": "etcd_server_proposals_failed_total", + "refId": "A", + "step": 2 + }, + { + "expr": "sum(etcd_server_proposals_pending{job=\"$cluster\"})", + "intervalFactor": 2, + "legendFormat": "Proposal Pending Total", + "metric": "etcd_server_proposals_pending", + "refId": "B", + "step": 2 + }, + { + "expr": "sum(rate(etcd_server_proposals_committed_total{job=\"$cluster\"}[$__rate_interval]))", + "intervalFactor": 2, + "legendFormat": "Proposal Commit Rate", + "metric": "etcd_server_proposals_committed_total", + "refId": "C", + "step": 2 + }, + { + "expr": "sum(rate(etcd_server_proposals_applied_total{job=\"$cluster\"}[$__rate_interval]))", + "intervalFactor": 2, + "legendFormat": "Proposal Apply Rate", + "refId": "D", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Raft Proposals", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "$datasource", + "decimals": 0, + "editable": true, + "error": false, + "fill": 0, + "id": 19, + "isNew": true, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "changes(etcd_server_leader_changes_seen_total{job=\"$cluster\"}[1d])", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Total Leader Elections Per Day", + "metric": "etcd_server_leader_changes_seen_total", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Total Leader Elections Per Day", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "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 + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": 0, + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 42, + "isNew": true, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.4.3", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (instance, le) (rate(etcd_network_peer_round_trip_time_seconds_bucket{job=\"$cluster\"}[$__rate_interval])))", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Peer round trip time", + "metric": "etcd_network_peer_round_trip_time_seconds_bucket", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Peer round trip time", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:925", + "decimals": null, + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:926", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "New row" + } + ], + "schemaVersion": 13, + "sharedCrosshair": false, + "style": "dark", + "tags": [ + "etcd-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "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": {{ if (or .Values.grafana.sidecar.dashboards.multicluster.global.enabled .Values.grafana.sidecar.dashboards.multicluster.etcd.enabled) }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [], + "query": "label_values(etcd_server_has_leader, job)", + "refresh": 2, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "etcd", + "uid": "c2f4e12cdf69feb95caa41a5a1b423d9", + "version": 215 + } +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/grafana-overview.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/grafana-overview.yaml new file mode 100644 index 0000000000..f8c8884d0b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/grafana-overview.yaml @@ -0,0 +1,635 @@ +{{- /* +Generated from 'grafana-overview' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "grafana-overview" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + grafana-overview.json: |- + { + "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" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 3085, + "iteration": 1631554945276, + "links": [ + + ], + "panels": [ + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "mappings": [ + + ], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + + ] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": { + + }, + "textMode": "auto" + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "expr": "grafana_alerting_result_total{job=~\"$job\", instance=~\"$instance\", state=\"alerting\"}", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Firing Alerts", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + + ] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": { + + }, + "textMode": "auto" + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "expr": "sum(grafana_stat_totals_dashboard{job=~\"$job\", instance=~\"$instance\"})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Dashboards", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { + "align": null, + "displayMode": "auto" + }, + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + + ] + }, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 10, + "options": { + "showHeader": true + }, + "pluginVersion": "8.1.3", + "targets": [ + { + "expr": "grafana_build_info{job=~\"$job\", instance=~\"$instance\"}", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Build Info", + "transformations": [ + { + "id": "labelsToFields", + "options": { + + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Value": true, + "branch": true, + "container": true, + "goversion": true, + "namespace": true, + "pod": true, + "revision": true + }, + "indexByName": { + "Time": 7, + "Value": 11, + "branch": 4, + "container": 8, + "edition": 2, + "goversion": 6, + "instance": 1, + "job": 0, + "namespace": 9, + "pod": 10, + "revision": 5, + "version": 3 + }, + "renameByName": { + + } + } + } + ], + "type": "table" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ] + }, + "overrides": [ + + ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 5 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status_code) (irate(grafana_http_request_duration_seconds_count{job=~\"$job\", instance=~\"$instance\"}[1m])) ", + "interval": "", + "legendFormat": "{{`{{`}}status_code{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeRegions": [ + + ], + "timeShift": null, + "title": "RPS", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "$$hashKey": "object:157", + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:158", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ] + }, + "overrides": [ + + ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 5 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.3", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(irate(grafana_http_request_duration_seconds_bucket{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) by (le)) * 1", + "interval": "", + "legendFormat": "99th Percentile", + "refId": "A" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.50, sum(irate(grafana_http_request_duration_seconds_bucket{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) by (le)) * 1", + "interval": "", + "legendFormat": "50th Percentile", + "refId": "B" + }, + { + "exemplar": true, + "expr": "sum(irate(grafana_http_request_duration_seconds_sum{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval])) * 1 / sum(irate(grafana_http_request_duration_seconds_count{instance=~\"$instance\", job=~\"$job\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "Average", + "refId": "C" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeRegions": [ + + ], + "timeShift": null, + "title": "Request Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "$$hashKey": "object:210", + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:211", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [ + + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Data Source", + "multi": false, + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": { + "selected": false, + "text": [ + "default/grafana" + ], + "value": [ + "default/grafana" + ] + }, + "datasource": "$datasource", + "definition": "label_values(grafana_build_info, job)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "job", + "options": [ + + ], + "query": { + "query": "label_values(grafana_build_info, job)", + "refId": "Billing Admin-job-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".*", + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "definition": "label_values(grafana_build_info, instance)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "instance", + "options": [ + + ], + "query": { + "query": "label_values(grafana_build_info, instance)", + "refId": "Billing Admin-instance-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Grafana Overview", + "uid": "6be0s85Mk", + "version": 2 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-coredns.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-coredns.yaml new file mode 100644 index 0000000000..7ecca76f23 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-coredns.yaml @@ -0,0 +1,1534 @@ +{{- /* +Generated from 'k8s-coredns' from ../files/dashboards/k8s-coredns.json +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.coreDns.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-coredns" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-coredns.json: |- + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "A dashboard for the CoreDNS DNS server with updated metrics for version 1.7.0+. Based on the CoreDNS dashboard by buhay.", + "editable": true, + "gnetId": 12539, + "graphTooltip": 0, + "iteration": 1603798405693, + "links": [ + { + "icon": "external link", + "tags": [], + "targetBlank": true, + "title": "CoreDNS.io", + "type": "link", + "url": "https://coredns.io" + } + ], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(coredns_dns_request_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (proto) or\nsum(rate(coredns_dns_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (proto)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}", + "refId": "A", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests (total)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total", + "yaxis": 2 + }, + { + "alias": "other", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(coredns_dns_request_type_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (type) or \nsum(rate(coredns_dns_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (type)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{type}}"}}", + "refId": "A", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests (by qtype)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(coredns_dns_request_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (zone) or\nsum(rate(coredns_dns_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (zone)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{zone}}"}}", + "refId": "A", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests (by zone)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(coredns_dns_request_do_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) or\nsum(rate(coredns_dns_do_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m]))", + "interval": "", + "intervalFactor": 2, + "legendFormat": "DO", + "refId": "A", + "step": 40 + }, + { + "expr": "sum(rate(coredns_dns_request_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) or\nsum(rate(coredns_dns_requests_total{job=\"coredns\",instance=~\"$instance\"}[5m]))", + "interval": "", + "intervalFactor": 2, + "legendFormat": "total", + "refId": "B", + "step": 40 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests (DO bit)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 7 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "tcp:90", + "yaxis": 2 + }, + { + "alias": "tcp:99 ", + "yaxis": 2 + }, + { + "alias": "tcp:50", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:99 ", + "refId": "A", + "step": 60 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:90", + "refId": "B", + "step": 60 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:50", + "refId": "C", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests (size, udp)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 7 + }, + "hiddenSeries": false, + "id": 12, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "tcp:90", + "yaxis": 1 + }, + { + "alias": "tcp:99 ", + "yaxis": 1 + }, + { + "alias": "tcp:50", + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:99 ", + "refId": "A", + "step": 60 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:90", + "refId": "B", + "step": 60 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:50", + "refId": "C", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests (size,tcp)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(coredns_dns_response_rcode_count_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (rcode) or\nsum(rate(coredns_dns_responses_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (rcode)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{rcode}}"}}", + "refId": "A", + "step": 40 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Responses (by rcode)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 14 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_duration_seconds_bucket{job=\"coredns\",instance=~\"$instance\"}[5m])) by (le, job))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99%", + "refId": "A", + "step": 40 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_duration_seconds_bucket{job=\"coredns\",instance=~\"$instance\"}[5m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "90%", + "refId": "B", + "step": 40 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_duration_seconds_bucket{job=\"coredns\",instance=~\"$instance\"}[5m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50%", + "refId": "C", + "step": 40 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Responses (duration)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 21 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "udp:50%", + "yaxis": 1 + }, + { + "alias": "tcp:50%", + "yaxis": 2 + }, + { + "alias": "tcp:90%", + "yaxis": 2 + }, + { + "alias": "tcp:99%", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:99%", + "refId": "A", + "step": 40 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:90%", + "refId": "B", + "step": 40 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:50%", + "metric": "", + "refId": "C", + "step": 40 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Responses (size, udp)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 21 + }, + "hiddenSeries": false, + "id": 20, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "udp:50%", + "yaxis": 1 + }, + { + "alias": "tcp:50%", + "yaxis": 1 + }, + { + "alias": "tcp:90%", + "yaxis": 1 + }, + { + "alias": "tcp:99%", + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto)) ", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:99%", + "refId": "A", + "step": 40 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto)) ", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:90%", + "refId": "B", + "step": 40 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_response_size_bytes_bucket{job=\"coredns\",instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le, proto)) ", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{"{{proto}}"}}:50%", + "metric": "", + "refId": "C", + "step": 40 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Responses (size, tcp)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 22, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(coredns_cache_size{job=\"coredns\",instance=~\"$instance\"}) by (type) or\nsum(coredns_cache_entries{job=\"coredns\",instance=~\"$instance\"}) by (type)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{"{{type}}"}}", + "refId": "A", + "step": 40 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Cache (size)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 28 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "misses", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(coredns_cache_hits_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (type)", + "hide": false, + "intervalFactor": 2, + "legendFormat": "hits:{{"{{type}}"}}", + "refId": "A", + "step": 40 + }, + { + "expr": "sum(rate(coredns_cache_misses_total{job=\"coredns\",instance=~\"$instance\"}[5m])) by (type)", + "hide": false, + "intervalFactor": 2, + "legendFormat": "misses", + "refId": "B", + "step": 40 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Cache (hitrate)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "10s", + "schemaVersion": 26, + "style": "dark", + "tags": [ + "dns", + "coredns" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "includeAll": false, + "label": "Data Source", + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "definition": "label_values(up{job=\"coredns\"}, instance)", + "hide": 0, + "includeAll": true, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [], + "query": "label_values(up{job=\"coredns\"}, instance)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 3, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "CoreDNS", + "uid": "vkQ0UHxik", + "version": 2 + } +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml new file mode 100644 index 0000000000..5c1193274e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-cluster.yaml @@ -0,0 +1,3088 @@ +{{- /* +Generated from 'k8s-resources-cluster' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-cluster" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-cluster.json: |- + { + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "100px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "percentunit", + "id": 1, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 2, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "cluster:node_cpu:ratio_rate5m{cluster=\"$cluster\"}", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "CPU Utilisation", + "tooltip": { + "shared": false, + "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": "percentunit", + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 2, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\",cluster=\"$cluster\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "CPU Requests Commitment", + "tooltip": { + "shared": false, + "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": "percentunit", + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 2, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\",cluster=\"$cluster\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "CPU Limits Commitment", + "tooltip": { + "shared": false, + "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": "percentunit", + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 2, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - sum(:node_memory_MemAvailable_bytes:sum{cluster=\"$cluster\"}) / sum(node_memory_MemTotal_bytes{job=\"node-exporter\",cluster=\"$cluster\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Memory Utilisation", + "tooltip": { + "shared": false, + "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": "percentunit", + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 2, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\",cluster=\"$cluster\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Memory Requests Commitment", + "tooltip": { + "shared": false, + "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": "percentunit", + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 2, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\",cluster=\"$cluster\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Memory Limits Commitment", + "tooltip": { + "shared": false, + "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": 10, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\"}) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": false, + "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": "CPU", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Pods", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell_1", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Workloads", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to workloads", + "linkUrl": "d/a87fb0d919ec0ea5f6543124e16c42a5/k8s-resources-workloads-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell_1", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "CPU Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #G", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Namespace", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell", + "pattern": "namespace", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(kube_pod_owner{job=\"kube-state-metrics\", cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "count(avg(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\"}) by (workload, namespace)) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\"}) by (namespace) / sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\"}) by (namespace) / sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "G", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "CPU Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 9, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage (w/o cache)", + "tooltip": { + "shared": false, + "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": "Memory", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Pods", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell_1", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Workloads", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to workloads", + "linkUrl": "d/a87fb0d919ec0ea5f6543124e16c42a5/k8s-resources-workloads-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell_1", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Memory Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #G", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Namespace", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell", + "pattern": "namespace", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(kube_pod_owner{job=\"kube-state-metrics\", cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "count(avg(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\"}) by (workload, namespace)) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace) / sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + }, + { + "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", container!=\"\"}) by (namespace) / sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\"$cluster\"}) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "G", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Requests by Namespace", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Memory Requests", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 11, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Current Receive Bandwidth", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Current Transmit Bandwidth", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Rate of Received Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Received Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Namespace", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell", + "pattern": "namespace", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Network Usage", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Current Network Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 12, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "tooltip": { + "shared": false, + "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, + "id": 13, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 14, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "avg(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Container Bandwidth by Namespace: Received", + "tooltip": { + "shared": false, + "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, + "id": 15, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "avg(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Container Bandwidth by Namespace: Transmitted", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Average Container Bandwidth by Namespace", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 16, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 17, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 18, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 19, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=~\".+\"}[$__rate_interval])) by (namespace)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets Dropped", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": -1, + "fill": 10, + "id": 20, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "ceil(sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval])))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "IOPS(Reads+Writes)", + "tooltip": { + "shared": false, + "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": 21, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}namespace{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "ThroughPut(Read+Write)", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Storage IO", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 22, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + + ], + "sort": { + "col": 4, + "desc": true + }, + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "IOPS(Reads)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "IOPS(Writes)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "IOPS(Reads + Writes)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Throughput(Read)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Throughput(Write)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Throughput(Read + Write)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Namespace", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$__cell", + "pattern": "namespace", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum by(namespace) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum by(namespace) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum by(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum by(namespace) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum by(namespace) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace!=\"\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Storage IO", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Storage IO - Distribution", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Compute Resources / Cluster", + "uid": "efa86fd1d0c121a26444b636a3f509a8", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml new file mode 100644 index 0000000000..75e1584201 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-multicluster.yaml @@ -0,0 +1,24 @@ +{{- /* +Generated from 'k8s-resources-multicluster' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-multicluster" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-multicluster.json: |- + {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"none"}},"gridPos":{"h":3,"w":4,"x":0,"y":0},"id":1,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"cluster:node_cpu:ratio_rate5m","instant":true}],"title":"CPU Utilisation","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":4,"y":0},"id":2,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"cpu\"})","instant":true}],"title":"CPU Requests Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":8,"y":0},"id":3,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"cpu\"})","instant":true}],"title":"CPU Limits Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":12,"y":0},"id":4,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"1 - sum(:node_memory_MemAvailable_bytes:sum) / sum(node_memory_MemTotal_bytes{job=\"node-exporter\"})","instant":true}],"title":"Memory Utilisation","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":16,"y":0},"id":5,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"memory\"})","instant":true}],"title":"Memory Requests Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":20,"y":0},"id":6,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) / sum(kube_node_status_allocatable{job=\"kube-state-metrics\", resource=\"memory\"})","instant":true}],"title":"Memory Limits Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"showPoints":"never"}}},"gridPos":{"h":7,"w":24,"x":0,"y":1},"id":7,"interval":"1m","options":{"legend":{"asTable":true,"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster)","legendFormat":"__auto"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Cluster"},"properties":[{"id":"links","value":[{"title":"Drill down","url":"/d/efa86fd1d0c121a26444b636a3f509a8/kubernetes-compute-resources-cluster?${datasource:queryparam}&var-cluster=${__data.fields.Cluster}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":2},"id":8,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate) by (cluster) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"cpu\"}) by (cluster)","format":"table","instant":true}],"title":"CPU Quota","transformations":[{"id":"joinByField","options":{"byField":"cluster","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"cluster":5},"renameByName":{"Value #A":"CPU Usage","Value #B":"CPU Requests","Value #C":"CPU Requests %","Value #D":"CPU Limits","Value #E":"CPU Limits %","cluster":"Cluster"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"showPoints":"never"},"unit":"bytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":3},"id":9,"interval":"1m","options":{"legend":{"asTable":true,"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster)","legendFormat":"__auto"}],"title":"Memory Usage (w/o cache)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Cluster"},"properties":[{"id":"links","value":[{"title":"Drill down","url":"/d/efa86fd1d0c121a26444b636a3f509a8/kubernetes-compute-resources-cluster?${datasource:queryparam}&var-cluster=${__data.fields.Cluster}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":4},"id":10,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", container!=\"\"}) by (cluster) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", resource=\"memory\"}) by (cluster)","format":"table","instant":true}],"title":"Memory Requests by Cluster","transformations":[{"id":"joinByField","options":{"byField":"cluster","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"cluster":5},"renameByName":{"Value #A":"Memory Usage","Value #B":"Memory Requests","Value #C":"Memory Requests %","Value #D":"Memory Limits","Value #E":"Memory Limits %","cluster":"Cluster"}}}],"type":"table"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Multi-Cluster","uid":"b59e6c9f2fcbe2e16d77fc492374cc4f"}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml new file mode 100644 index 0000000000..896b0b2d92 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-namespace.yaml @@ -0,0 +1,2797 @@ +{{- /* +Generated from 'k8s-resources-namespace' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-namespace" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-namespace.json: |- + { + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "100px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "percentunit", + "id": 1, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "CPU Utilisation (from requests)", + "tooltip": { + "shared": false, + "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": "percentunit", + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "CPU Utilisation (from limits)", + "tooltip": { + "shared": false, + "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": "percentunit", + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Memory Utilisation (from requests)", + "tooltip": { + "shared": false, + "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": "percentunit", + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) / sum(kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Memory Utilisation (from limits)", + "tooltip": { + "shared": false, + "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": 10, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "quota - requests", + "color": "#F2495C", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + }, + { + "alias": "quota - limits", + "color": "#FF9830", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + } + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.cpu\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "quota - requests", + "legendLink": null, + "step": 10 + }, + { + "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.cpu\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "quota - limits", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": false, + "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": "CPU Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "CPU Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "CPU Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "CPU Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "quota - requests", + "color": "#F2495C", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + }, + { + "alias": "quota - limits", + "color": "#FF9830", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + } + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.memory\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "quota - requests", + "legendLink": null, + "step": 10 + }, + { + "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.memory\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "quota - limits", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage (w/o cache)", + "tooltip": { + "shared": false, + "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": "Memory Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Memory Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Usage (RSS)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Usage (Cache)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #G", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Usage (Swap)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #H", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + }, + { + "expr": "sum(container_memory_cache{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "G", + "step": 10 + }, + { + "expr": "sum(container_memory_swap{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "H", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Memory Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 9, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Current Receive Bandwidth", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Current Transmit Bandwidth", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Rate of Received Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Received Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Network Usage", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Current Network Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "tooltip": { + "shared": false, + "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, + "id": 11, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 12, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 13, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 14, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 15, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets Dropped", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": -1, + "fill": 10, + "id": 16, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "ceil(sum by(pod) (rate(container_fs_reads_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "IOPS(Reads+Writes)", + "tooltip": { + "shared": false, + "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": 17, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(pod) (rate(container_fs_reads_bytes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{container!=\"\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "ThroughPut(Read+Write)", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Storage IO", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 18, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + + ], + "sort": { + "col": 4, + "desc": true + }, + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "IOPS(Reads)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "IOPS(Writes)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "IOPS(Reads + Writes)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Throughput(Read)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Throughput(Write)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Throughput(Read + Write)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum by(pod) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum by(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum by(pod) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum by(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Storage IO", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Storage IO - Distribution", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Compute Resources / Namespace (Pods)", + "uid": "85a562078cdf77779eaa1add43ccec1e", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-node.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-node.yaml new file mode 100644 index 0000000000..ab9c76efe0 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-node.yaml @@ -0,0 +1,1026 @@ +{{- /* +Generated from 'k8s-resources-node' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-node" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-node.json: |- + { + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 1, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "max capacity", + "color": "#F2495C", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + } + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(kube_node_status_capacity{cluster=\"$cluster\", node=~\"$node\", resource=\"cpu\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "max capacity", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": false, + "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": "CPU Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "CPU Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "CPU Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", node=~\"$node\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", node=~\"$node\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "CPU Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "max capacity", + "color": "#F2495C", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + } + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(kube_node_status_capacity{cluster=\"$cluster\", node=~\"$node\", resource=\"memory\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "max capacity", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\", container!=\"\"}) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage (w/o cache)", + "tooltip": { + "shared": false, + "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": "Memory Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Memory Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Usage (RSS)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Usage (Cache)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #G", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Usage (Swap)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #H", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", node=~\"$node\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_memory_rss{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_memory_cache{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "G", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_memory_swap{cluster=\"$cluster\", node=~\"$node\",container!=\"\"}) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "H", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Memory Quota", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": true, + "name": "node", + "options": [ + + ], + "query": "label_values(kube_node_info{cluster=\"$cluster\"}, node)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Compute Resources / Node (Pods)", + "uid": "200ac8fdbfbb74b39aff88118e4d1c2c", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml new file mode 100644 index 0000000000..0a6da86c15 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-pod.yaml @@ -0,0 +1,2469 @@ +{{- /* +Generated from 'k8s-resources-pod' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-pod" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-pod.json: |- + { + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 1, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "requests", + "color": "#F2495C", + "fill": 0, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + }, + { + "alias": "limits", + "color": "#FF9830", + "fill": 0, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + } + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$namespace\", pod=\"$pod\", cluster=\"$cluster\"}) by (container)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}container{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"cpu\"}\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "requests", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"cpu\"}\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limits", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": false, + "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": "CPU Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "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": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(container_cpu_cfs_throttled_periods_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", cluster=\"$cluster\"}[$__rate_interval])) by (container) /sum(increase(container_cpu_cfs_periods_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", cluster=\"$cluster\"}[$__rate_interval])) by (container)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}container{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + { + "colorMode": "critical", + "fill": true, + "line": true, + "op": "gt", + "value": 0.25, + "yaxis": "left" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Throttling", + "tooltip": { + "shared": false, + "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": 1, + "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": "CPU Throttling", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "CPU Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "CPU Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Container", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "container", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "CPU Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "requests", + "color": "#F2495C", + "dashes": true, + "fill": 0, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + }, + { + "alias": "limits", + "color": "#FF9830", + "dashes": true, + "fill": 0, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + } + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}container{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"memory\"}\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "requests", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", resource=\"memory\"}\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limits", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage (WSS)", + "tooltip": { + "shared": false, + "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": "Memory Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Memory Usage (WSS)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Usage (RSS)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Usage (Cache)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #G", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Usage (Swap)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #H", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Container", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "container", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", image!=\"\"}) by (container) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container!=\"\", image!=\"\"}) by (container) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(container_memory_rss{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + }, + { + "expr": "sum(container_memory_cache{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "G", + "step": 10 + }, + { + "expr": "sum(container_memory_swap{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\", container != \"\", container != \"POD\"}) by (container)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "H", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Memory Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "tooltip": { + "shared": false, + "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, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 11, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) by (pod)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets Dropped", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": -1, + "fill": 10, + "id": 12, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "ceil(sum by(pod) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Reads", + "legendLink": null, + "step": 10 + }, + { + "expr": "ceil(sum by(pod) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\",namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Writes", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "IOPS", + "tooltip": { + "shared": false, + "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": 13, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(pod) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Reads", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum by(pod) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Writes", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "ThroughPut", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Storage IO - Distribution(Pod - Read & Writes)", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "decimals": -1, + "fill": 10, + "id": 14, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "ceil(sum by(container) (rate(container_fs_reads_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval])))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}container{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "IOPS(Reads+Writes)", + "tooltip": { + "shared": false, + "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": 15, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(container) (rate(container_fs_reads_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}container{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "ThroughPut(Read+Write)", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Storage IO - Distribution(Containers)", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 16, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + + ], + "sort": { + "col": 4, + "desc": true + }, + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "IOPS(Reads)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "IOPS(Writes)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "IOPS(Reads + Writes)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": -1, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Throughput(Read)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Throughput(Write)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Throughput(Read + Write)", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Container", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "container", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum by(container) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum by(container) (rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\",device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum by(container) (rate(container_fs_reads_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum by(container) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum by(container) (rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum by(container) (rate(container_fs_reads_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\", container!=\"\", cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[$__rate_interval]))", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Storage IO", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Storage IO - Distribution", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "pod", + "options": [ + + ], + "query": "label_values(kube_pod_info{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\"}, pod)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Compute Resources / Pod", + "uid": "6581e46e4e5c7ba40a07646395ef7b23", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml new file mode 100644 index 0000000000..6def97a796 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-cluster.yaml @@ -0,0 +1,24 @@ +{{- /* +Generated from 'k8s-resources-windows-cluster' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-windows-cluster" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-windows-cluster.json: |- + {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"none"}},"gridPos":{"h":3,"w":4,"x":0,"y":0},"id":1,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"1 - avg(rate(windows_cpu_time_total{cluster=\"$cluster\", job=\"windows-exporter\", mode=\"idle\"}[1m]))","instant":true}],"title":"CPU Utilisation","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":4,"y":0},"id":2,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) / sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"})","instant":true}],"title":"CPU Requests Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":8,"y":0},"id":3,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) / sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"})","instant":true}],"title":"CPU Limits Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":12,"y":0},"id":4,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"1 - sum(:windows_node_memory_MemFreeCached_bytes:sum{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","instant":true}],"title":"Memory Utilisation","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":16,"y":0},"id":5,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","instant":true}],"title":"Memory Requests Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"percentunit"}},"gridPos":{"h":3,"w":4,"x":20,"y":0},"id":6,"interval":"1m","options":{"colorMode":"none"},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\"$cluster\"})","instant":true}],"title":"Memory Limits Commitment","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true}}},"gridPos":{"h":7,"w":24,"x":0,"y":7},"id":7,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace)","legendFormat":"__auto"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Namespace"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":14},"id":8,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true}],"title":"CPU Quota","transformations":[{"id":"joinByField","options":{"byField":"namespace","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"namespace":5},"renameByName":{"Value #A":"CPU Usage","Value #B":"CPU Requests","Value #C":"CPU Requests %","Value #D":"CPU Limits","Value #E":"CPU Limits %","namespace":"Namespace"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"decbytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":21},"id":9,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace)","legendFormat":"__auto"}],"title":"Memory Usage (Private Working Set)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Memory Usage"},"properties":[{"id":"unit","value":"decbytes"}]},{"matcher":{"id":"byName","options":"Memory Requests"},"properties":[{"id":"unit","value":"decbytes"}]},{"matcher":{"id":"byName","options":"Memory Limits"},"properties":[{"id":"unit","value":"decbytes"}]},{"matcher":{"id":"byName","options":"Namespace"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":28},"id":10,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\"}) by (namespace) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\"}) by (namespace)","format":"table","instant":true}],"title":"Memory Requests by Namespace","transformations":[{"id":"joinByField","options":{"byField":"namespace","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"namespace":5},"renameByName":{"Value #A":"Memory Usage","Value #B":"Memory Requests","Value #C":"Memory Requests %","Value #D":"Memory Limits","Value #E":"Memory Limits %","namespace":"Namespace"}}}],"type":"table"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Cluster(Windows)","uid":"4d08557fd9391b100730f2494bccac68"}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml new file mode 100644 index 0000000000..2dfd58bed1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-namespace.yaml @@ -0,0 +1,24 @@ +{{- /* +Generated from 'k8s-resources-windows-namespace' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-windows-namespace" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-windows-namespace.json: |- + {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true}}},"gridPos":{"h":7,"w":24,"x":0,"y":0},"id":1,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","legendFormat":"__auto"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Pod"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":7},"id":2,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true}],"title":"CPU Quota","transformations":[{"id":"joinByField","options":{"byField":"pod","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"pod":5},"renameByName":{"Value #A":"CPU Usage","Value #B":"CPU Requests","Value #C":"CPU Requests %","Value #D":"CPU Limits","Value #E":"CPU Limits %","pod":"Pod"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"decbytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":14},"id":3,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","legendFormat":"__auto"}],"title":"Memory Usage (Private Working Set)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Pod"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":21},"id":4,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\"}) by (pod)","format":"table","instant":true}],"title":"Memory Quota","transformations":[{"id":"joinByField","options":{"byField":"pod","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"pod":5},"renameByName":{"Value #A":"Memory Usage","Value #B":"Memory Requests","Value #C":"Memory Requests %","Value #D":"Memory Limits","Value #E":"Memory Limits %","pod":"Pod"}}}],"type":"table"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":0,"label":"namespace","name":"namespace","query":"label_values(windows_pod_container_available{cluster=\"$cluster\"}, namespace)","refresh":2,"sort":1,"type":"query"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Namespace(Windows)","uid":"490b402361724ab1d4c45666c1fa9b6f"}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml new file mode 100644 index 0000000000..4417b31a6e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-windows-pod.yaml @@ -0,0 +1,24 @@ +{{- /* +Generated from 'k8s-resources-windows-pod' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-windows-pod" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-windows-pod.json: |- + {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true}}},"gridPos":{"h":7,"w":24,"x":0,"y":0},"id":1,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","legendFormat":"__auto"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]},{"matcher":{"id":"byName","options":"Namespace"},"properties":[{"id":"links","value":[{"title":"Drill down to pods","url":"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":7},"id":2,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true}],"title":"CPU Quota","transformations":[{"id":"joinByField","options":{"byField":"container","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"container":5},"renameByName":{"Value #A":"CPU Usage","Value #B":"CPU Requests","Value #C":"CPU Requests %","Value #D":"CPU Limits","Value #E":"CPU Limits %","container":"Container"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"decbytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":14},"id":3,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","legendFormat":"__auto"}],"title":"Memory Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/%/"},"properties":[{"id":"unit","value":"percentunit"}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":21},"id":4,"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_memory_request{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(windows_container_private_working_set_usage{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}) by (container)","format":"table","instant":true}],"title":"Memory Quota","transformations":[{"id":"joinByField","options":{"byField":"container","mode":"outer"}},{"id":"organize","options":{"excludeByName":{"Time":true,"Time 1":true,"Time 2":true,"Time 3":true,"Time 4":true,"Time 5":true},"indexByName":{"Time 1":0,"Time 2":1,"Time 3":2,"Time 4":3,"Time 5":4,"Value #A":6,"Value #B":7,"Value #C":8,"Value #D":9,"Value #E":10,"container":5},"renameByName":{"Value #A":"Memory Usage","Value #B":"Memory Requests","Value #C":"Memory Requests %","Value #D":"Memory Limits","Value #E":"Memory Limits %","container":"Container"}}}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"bytes"}},"gridPos":{"h":7,"w":24,"x":0,"y":28},"id":5,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sort_desc(sum by (container) (rate(windows_container_network_received_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[1m])))","legendFormat":"Received : {{ container }}"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sort_desc(sum by (container) (rate(windows_container_network_transmitted_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=\"$pod\"}[1m])))","legendFormat":"Transmitted : {{ container }}"}],"title":"Network I/O","type":"timeseries"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":0,"label":"namespace","name":"namespace","query":"label_values(windows_pod_container_available{cluster=\"$cluster\"}, namespace)","refresh":2,"sort":1,"type":"query"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":0,"label":"pod","name":"pod","query":"label_values(windows_pod_container_available{cluster=\"$cluster\",namespace=\"$namespace\"}, pod)","refresh":2,"sort":1,"type":"query"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / Compute Resources / Pod(Windows)","uid":"40597a704a610e936dc6ed374a7ce023"}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml new file mode 100644 index 0000000000..a1bd68b805 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workload.yaml @@ -0,0 +1,2024 @@ +{{- /* +Generated from 'k8s-resources-workload' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-workload" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-workload.json: |- + { + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 1, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": false, + "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": "CPU Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "CPU Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "CPU Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "CPU Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": false, + "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": "Memory Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Memory Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(\n container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=\"$workload\", workload_type=\"$type\"}\n) by (pod)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Memory Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Current Receive Bandwidth", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Current Transmit Bandwidth", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Rate of Received Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Received Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-pod=$__cell", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "(sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Network Usage", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Current Network Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "tooltip": { + "shared": false, + "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, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "(avg(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Container Bandwidth by Pod: Received", + "tooltip": { + "shared": false, + "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, + "id": 9, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "(avg(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Container Bandwidth by Pod: Transmitted", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Average Container Bandwidth by Pod", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 11, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 12, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 13, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets Dropped", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(kube_namespace_status_phase{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "type", + "options": [ + + ], + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\"}, workload_type)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "workload", + "options": [ + + ], + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}, workload)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Compute Resources / Workload", + "uid": "a164a7f0339f99e89cea5cb47e9be617", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml new file mode 100644 index 0000000000..09257b911e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-resources-workloads-namespace.yaml @@ -0,0 +1,2189 @@ +{{- /* +Generated from 'k8s-resources-workloads-namespace' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-resources-workloads-namespace" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-resources-workloads-namespace.json: |- + { + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 1, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "quota - requests", + "color": "#F2495C", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + }, + { + "alias": "quota - limits", + "color": "#FF9830", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + } + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}} - {{`{{`}}workload_type{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.cpu\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "quota - requests", + "legendLink": null, + "step": 10 + }, + { + "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.cpu\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "quota - limits", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": false, + "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": "CPU Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Running Pods", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "CPU Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "CPU Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Workload", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-workload=$__cell&var-type=$__cell_2", + "pattern": "workload", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Workload Type", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "workload_type", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "count(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload, workload_type)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(\n node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"cpu\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "CPU Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ + + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "quota - requests", + "color": "#F2495C", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + }, + { + "alias": "quota - limits", + "color": "#FF9830", + "dashes": true, + "fill": 0, + "hiddenSeries": true, + "hideTooltip": true, + "legend": true, + "linewidth": 2, + "stack": false + } + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(\n container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}} - {{`{{`}}workload_type{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"requests.memory\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "quota - requests", + "legendLink": null, + "step": 10 + }, + { + "expr": "scalar(kube_resourcequota{cluster=\"$cluster\", namespace=\"$namespace\", type=\"hard\",resource=\"limits.memory\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "quota - limits", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": false, + "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": "Memory Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Running Pods", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Memory Usage", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Requests %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Memory Limits", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Memory Limits %", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Workload", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-workload=$__cell&var-type=$__cell_2", + "pattern": "workload", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Workload Type", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "workload_type", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "count(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload, workload_type)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(\n container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(\n container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_requests{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(\n container_memory_working_set_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\", container!=\"\", image!=\"\"}\n * on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n/sum(\n kube_pod_container_resource_limits{job=\"kube-state-metrics\", cluster=\"$cluster\", namespace=\"$namespace\", resource=\"memory\"}\n* on(namespace,pod)\n group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}\n) by (workload, workload_type)\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Quota", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Memory Quota", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Current Receive Bandwidth", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Current Transmit Bandwidth", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Rate of Received Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Received Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Workload", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": false, + "linkTooltip": "Drill down to pods", + "linkUrl": "d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?var-datasource=$datasource&var-cluster=$cluster&var-namespace=$namespace&var-workload=$__cell&var-type=$type", + "pattern": "workload", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Workload Type", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "workload_type", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "(sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "(sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Network Usage", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Current Network Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "tooltip": { + "shared": false, + "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, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "(avg(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Container Bandwidth by Workload: Received", + "tooltip": { + "shared": false, + "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, + "id": 9, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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": "(avg(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Container Bandwidth by Workload: Transmitted", + "tooltip": { + "shared": false, + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Average Container Bandwidth by Workload", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 11, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 12, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": 13, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "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(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\", namespace=\"$namespace\"}[$__rate_interval])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "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": "Rate of Packets Dropped", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(kube_pod_info{job=\"kube-state-metrics\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "deployment", + "value": "deployment" + }, + "datasource": "$datasource", + "definition": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\"}, workload_type)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "type", + "options": [ + + ], + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\", namespace=\"$namespace\", workload=~\".+\"}, workload_type)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Compute Resources / Namespace (Workloads)", + "uid": "a87fb0d919ec0ea5f6543124e16c42a5", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml new file mode 100644 index 0000000000..0c4a2ca998 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-cluster-rsrc-use.yaml @@ -0,0 +1,24 @@ +{{- /* +Generated from 'k8s-windows-cluster-rsrc-use' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-windows-cluster-rsrc-use" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-windows-cluster-rsrc-use.json: |- + {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":24,"x":0,"y":0},"id":1,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_cpu_utilisation:avg1m{cluster=\"$cluster\"} * node:windows_node_num_cpu:sum{cluster=\"$cluster\"} / scalar(sum(node:windows_node_num_cpu:sum{cluster=\"$cluster\"}))","legendFormat":"{{instance}}"}],"title":"CPU Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":12,"x":0,"y":7},"id":2,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_memory_utilisation:ratio{cluster=\"$cluster\"}","legendFormat":"{{instance}}"}],"title":"Memory Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"short"}},"gridPos":{"h":7,"w":12,"x":12,"y":7},"id":3,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_memory_swap_io_pages:irate{cluster=\"$cluster\"}","legendFormat":"{{instance}}"}],"title":"Memory Saturation (Swap I/O Pages)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":24,"x":0,"y":14},"id":4,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_disk_utilisation:avg_irate{cluster=\"$cluster\"} / scalar(node:windows_node:sum{cluster=\"$cluster\"})","legendFormat":"{{instance}}"}],"title":"Disk IO Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"Bps"}},"gridPos":{"h":7,"w":12,"x":0,"y":21},"id":5,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_net_utilisation:sum_irate{cluster=\"$cluster\"}","legendFormat":"{{instance}}"}],"title":"Net Utilisation (Transmitted)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"Bps"}},"gridPos":{"h":7,"w":12,"x":12,"y":21},"id":6,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_net_saturation:sum_irate{cluster=\"$cluster\"}","legendFormat":"{{instance}}"}],"title":"Net Utilisation (Dropped)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":24,"x":0,"y":28},"id":7,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum by (instance)(node:windows_node_filesystem_usage:{cluster=\"$cluster\"})","legendFormat":"{{instance}}"}],"title":"Disk Capacity","type":"timeseries"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / USE Method / Cluster(Windows)","uid":"53a43377ec9aaf2ff64dfc7a1f539334"}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml new file mode 100644 index 0000000000..890cef3a8d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/k8s-windows-node-rsrc-use.yaml @@ -0,0 +1,24 @@ +{{- /* +Generated from 'k8s-windows-node-rsrc-use' from https://github.com/kubernetes-monitoring/kubernetes-mixin.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.windowsMonitoring.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "k8s-windows-node-rsrc-use" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + k8s-windows-node-rsrc-use.json: |- + {{`{"editable":`}}{{ .Values.grafana.defaultDashboardsEditable }}{{`,"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":12,"x":0,"y":0},"id":1,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_cpu_utilisation:avg1m{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Utilisation"}],"title":"CPU Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":12,"x":12,"y":0},"id":2,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum by (core) (irate(windows_cpu_time_total{cluster=\"$cluster\", job=\"windows-exporter\", mode!=\"idle\", instance=\"$instance\"}[$__rate_interval]))","legendFormat":"{{core}}"}],"title":"CPU Usage Per Core","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":8,"x":0,"y":7},"id":3,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_memory_utilisation:{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Memory"}],"title":"Memory Utilisation %","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"bytes"}},"gridPos":{"h":7,"w":8,"x":8,"y":7},"id":4,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(\n windows_os_visible_memory_bytes{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}\n - windows_memory_available_bytes{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}\n)\n","legendFormat":"memory used"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(node:windows_node_memory_totalCached_bytes:sum{cluster=\"$cluster\", instance=\"$instance\"})","legendFormat":"memory cached"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(windows_memory_available_bytes{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"})","legendFormat":"memory free"}],"title":"Memory Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"short"}},"gridPos":{"h":7,"w":8,"x":16,"y":7},"id":5,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_memory_swap_io_pages:irate{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Swap IO"}],"title":"Memory Saturation (Swap I/O) Pages","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":12,"x":0,"y":14},"id":6,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_disk_utilisation:avg_irate{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Utilisation"}],"title":"Disk IO Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"bytes"},"overrides":[{"matcher":{"id":"byRegexp","options":"/io time/"},"properties":[{"id":"unit","value":"ms"}]}]},"gridPos":{"h":7,"w":12,"x":12,"y":14},"id":7,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(rate(windows_logical_disk_read_bytes_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]))","legendFormat":"read"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(rate(windows_logical_disk_write_bytes_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]))","legendFormat":"written"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"max(rate(windows_logical_disk_read_seconds_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]) + rate(windows_logical_disk_write_seconds_total{cluster=\"$cluster\", job=\"windows-exporter\", instance=\"$instance\"}[2m]))","legendFormat":"io time"}],"title":"Disk IO","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"percentunit"}},"gridPos":{"h":7,"w":24,"x":0,"y":21},"id":8,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_filesystem_usage:{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"{{volume}}"}],"title":"Disk Utilisation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"Bps"}},"gridPos":{"h":7,"w":12,"x":0,"y":28},"id":9,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_net_utilisation:sum_irate{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Utilisation"}],"title":"Net Utilisation (Transmitted)","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"showPoints":"never","spanNulls":true},"unit":"Bps"}},"gridPos":{"h":7,"w":12,"x":12,"y":28},"id":10,"interval":"1m","options":{"legend":{"asTable":true,"calcs":["lastNotNull"],"displayMode":"table","placement":"right","showLegend":true},"tooltip":{"mode":"single"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"node:windows_node_net_saturation:sum_irate{cluster=\"$cluster\", instance=\"$instance\"}","legendFormat":"Saturation"}],"title":"Net Saturation (Dropped)","type":"timeseries"}],"refresh":"10s","schemaVersion":39,"tags":["kubernetes-mixin"],"templating":{"list":[{"current":{"selected":true,"text":"default","value":"default"},"hide":0,"label":"Data source","name":"datasource","query":"prometheus","regex":"","type":"datasource"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":`}}{{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}{{`,"label":"cluster","name":"cluster","query":"label_values(up{job=\"windows-exporter\"}, cluster)","refresh":2,"sort":1,"type":"query","allValue":".*"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"hide":0,"label":"instance","multi":true,"name":"instance","query":"label_values(windows_system_system_up_time{cluster=\"$cluster\"}, instance)","refresh":2,"type":"query"}]},"time":{"from":"now-1h","to":"now"},"timezone": "`}}{{ .Values.grafana.defaultDashboardsTimezone }}{{`","title":"Kubernetes / USE Method / Node(Windows)","uid":"96e7484b0bb53b74fbc2bcb7723cd40b"}`}} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/kubelet.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/kubelet.yaml new file mode 100644 index 0000000000..bdbf1c2195 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/kubelet.yaml @@ -0,0 +1,2256 @@ +{{- /* +Generated from 'kubelet' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +{{- if (include "exporter.kubelet.enabled" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "kubelet" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + kubelet.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "panels": [ + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ], + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + + ] + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 2, + "links": [ + + ], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7", + "targets": [ + { + "expr": "sum(kubelet_node_name{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "title": "Running Kubelets", + "transparent": false, + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ], + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + + ] + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 4, + "y": 0 + }, + "id": 3, + "links": [ + + ], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7", + "targets": [ + { + "expr": "sum(kubelet_running_pods{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}) OR sum(kubelet_running_pod_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "title": "Running Pods", + "transparent": false, + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ], + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + + ] + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 8, + "y": 0 + }, + "id": 4, + "links": [ + + ], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7", + "targets": [ + { + "expr": "sum(kubelet_running_containers{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}) OR sum(kubelet_running_container_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "title": "Running Containers", + "transparent": false, + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ], + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + + ] + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 12, + "y": 0 + }, + "id": 5, + "links": [ + + ], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7", + "targets": [ + { + "expr": "sum(volume_manager_total_volumes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\", state=\"actual_state_of_world\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "title": "Actual Volume Count", + "transparent": false, + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ], + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + + ] + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 16, + "y": 0 + }, + "id": 6, + "links": [ + + ], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7", + "targets": [ + { + "expr": "sum(volume_manager_total_volumes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",state=\"desired_state_of_world\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "title": "Desired Volume Count", + "transparent": false, + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [ + + ], + "mappings": [ + + ], + "thresholds": { + "mode": "absolute", + "steps": [ + + ] + }, + "unit": "none" + } + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 20, + "y": 0 + }, + "id": 7, + "links": [ + + ], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7", + "targets": [ + { + "expr": "sum(rate(kubelet_node_config_error{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "title": "Config Error Count", + "transparent": false, + "type": "stat" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 8, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(kubelet_runtime_operations_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (operation_type, instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_type{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Operation Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 9, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(kubelet_runtime_operations_errors_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_type{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Operation Error Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(kubelet_runtime_operations_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_type{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Operation duration 99th quantile", + "tooltip": { + "shared": true, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 11, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(kubelet_pod_start_duration_seconds_count{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} pod", + "refId": "A" + }, + { + "expr": "sum(rate(kubelet_pod_worker_duration_seconds_count{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} worker", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Pod Start Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 12, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} pod", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(kubelet_pod_worker_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} worker", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Pod Start Duration", + "tooltip": { + "shared": true, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 28 + }, + "id": 13, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(storage_operation_duration_seconds_count{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_name{{`}}`}} {{`{{`}}volume_plugin{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Storage Operation Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 28 + }, + "id": 14, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(storage_operation_errors_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_name{{`}}`}} {{`{{`}}volume_plugin{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Storage Operation Error Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 15, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(storage_operation_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_name, volume_plugin, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_name{{`}}`}} {{`{{`}}volume_plugin{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Storage Operation Duration 99th quantile", + "tooltip": { + "shared": true, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 16, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(kubelet_cgroup_manager_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}operation_type{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Cgroup manager operation rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 17, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(kubelet_cgroup_manager_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, operation_type, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}operation_type{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Cgroup manager 99th quantile", + "tooltip": { + "shared": true, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Pod lifecycle event generator", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 49 + }, + "id": 18, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(kubelet_pleg_relist_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "PLEG relist rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 49 + }, + "id": 19, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_interval_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "PLEG relist interval", + "tooltip": { + "shared": true, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 56 + }, + "id": 20, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "PLEG relist duration", + "tooltip": { + "shared": true, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 63 + }, + "id": 21, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "2xx", + "refId": "A" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "3xx", + "refId": "B" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "4xx", + "refId": "C" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "5xx", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "RPC Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 70 + }, + "id": 22, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", instance=~\"$instance\"}[$__rate_interval])) by (instance, verb, url, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Request duration 99th quantile", + "tooltip": { + "shared": true, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 77 + }, + "id": 23, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": true, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 77 + }, + "id": 24, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU usage", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 77 + }, + "id": 25, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_goroutines{cluster=\"$cluster\",job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Goroutines", + "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 + } + ] + } + ], + "refresh": "10s", + "rows": [ + + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": "instance", + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\",cluster=\"$cluster\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Kubelet", + "uid": "3138fa155d5915769fbded898ac09fd9", + "version": 0 + } +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-pod.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-pod.yaml new file mode 100644 index 0000000000..92882d7dba --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-pod.yaml @@ -0,0 +1,1464 @@ +{{- /* +Generated from 'namespace-by-pod' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "namespace-by-pod" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + namespace-by-pod.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "panels": [ + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Current Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "decimals": 0, + "format": "time_series", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 1 + }, + "height": 9, + "id": 3, + "interval": null, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "minSpan": 12, + "nullPointMode": "connected", + "nullText": null, + "options": { + "fieldOptions": { + "calcs": [ + "last" + ], + "defaults": { + "max": 10000000000, + "min": 0, + "title": "$namespace", + "unit": "Bps" + }, + "mappings": [ + + ], + "override": { + + }, + "thresholds": [ + { + "color": "dark-green", + "index": 0, + "value": null + }, + { + "color": "dark-yellow", + "index": 1, + "value": 5000000000 + }, + { + "color": "dark-red", + "index": 2, + "value": 7000000000 + } + ], + "values": false + } + }, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 12, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution]))", + "format": "time_series", + "instant": null, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Received", + "type": "gauge", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "decimals": 0, + "format": "time_series", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 1 + }, + "height": 9, + "id": 4, + "interval": null, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "minSpan": 12, + "nullPointMode": "connected", + "nullText": null, + "options": { + "fieldOptions": { + "calcs": [ + "last" + ], + "defaults": { + "max": 10000000000, + "min": 0, + "title": "$namespace", + "unit": "Bps" + }, + "mappings": [ + + ], + "override": { + + }, + "thresholds": [ + { + "color": "dark-green", + "index": 0, + "value": null + }, + { + "color": "dark-yellow", + "index": 1, + "value": 5000000000 + }, + { + "color": "dark-red", + "index": 2, + "value": 7000000000 + } + ], + "values": false + } + }, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 12, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution]))", + "format": "time_series", + "instant": null, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Transmitted", + "type": "gauge", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "columns": [ + { + "text": "Time", + "value": "Time" + }, + { + "text": "Value #A", + "value": "Value #A" + }, + { + "text": "Value #B", + "value": "Value #B" + }, + { + "text": "Value #C", + "value": "Value #C" + }, + { + "text": "Value #D", + "value": "Value #D" + }, + { + "text": "Value #E", + "value": "Value #E" + }, + { + "text": "Value #F", + "value": "Value #F" + }, + { + "text": "pod", + "value": "pod" + } + ], + "datasource": "$datasource", + "fill": 1, + "fontSize": "100%", + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 5, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null as zero", + "renderer": "flot", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": false + }, + "spaceLength": 10, + "span": 24, + "styles": [ + { + "alias": "Time", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Time", + "thresholds": [ + + ], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Bandwidth Received", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Bandwidth Transmitted", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Rate of Received Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Received Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Pod", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTooltip": "Drill down", + "linkUrl": "d/7a18067ce943a40ae25454675c19ff5c/kubernetes-networking-pod?orgId=1&refresh=30s&var-namespace=$namespace&var-pod=$__cell", + "pattern": "pod", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Status", + "type": "table" + }, + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 6, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 7, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 8, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 29 + }, + "id": 9, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 30 + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 30 + }, + "id": 11, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Packets", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 12, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 40 + }, + "id": 13, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 40 + }, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Errors", + "titleSize": "h6", + "type": "row" + } + ], + "refresh": "10s", + "rows": [ + + ], + "schemaVersion": 18, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".+", + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "kube-system", + "value": "kube-system" + }, + "datasource": "$datasource", + "definition": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "resolution", + "options": [ + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": true, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + } + ], + "query": "30s,5m,1h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 2, + "includeAll": false, + "label": null, + "multi": false, + "name": "interval", + "options": [ + { + "selected": true, + "text": "4h", + "value": "4h" + } + ], + "query": "4h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Networking / Namespace (Pods)", + "uid": "8b7a8b326d7a6f1f04244066368c67af", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-workload.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-workload.yaml new file mode 100644 index 0000000000..5abea97774 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/namespace-by-workload.yaml @@ -0,0 +1,1736 @@ +{{- /* +Generated from 'namespace-by-workload' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "namespace-by-workload" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + namespace-by-workload.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "panels": [ + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Current Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}} workload {{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Received", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}} workload {{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Transmitted", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "columns": [ + { + "text": "Time", + "value": "Time" + }, + { + "text": "Value #A", + "value": "Value #A" + }, + { + "text": "Value #B", + "value": "Value #B" + }, + { + "text": "Value #C", + "value": "Value #C" + }, + { + "text": "Value #D", + "value": "Value #D" + }, + { + "text": "Value #E", + "value": "Value #E" + }, + { + "text": "Value #F", + "value": "Value #F" + }, + { + "text": "Value #G", + "value": "Value #G" + }, + { + "text": "Value #H", + "value": "Value #H" + }, + { + "text": "workload", + "value": "workload" + } + ], + "datasource": "$datasource", + "fill": 1, + "fontSize": "90%", + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 5, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null as zero", + "renderer": "flot", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": false + }, + "spaceLength": 10, + "span": 24, + "styles": [ + { + "alias": "Time", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Time", + "thresholds": [ + + ], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Current Bandwidth Received", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Current Bandwidth Transmitted", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Average Bandwidth Received", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #C", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Average Bandwidth Transmitted", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #D", + "thresholds": [ + + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Rate of Received Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #E", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #F", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Received Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #G", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Rate of Transmitted Packets Dropped", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #H", + "thresholds": [ + + ], + "type": "number", + "unit": "pps" + }, + { + "alias": "Workload", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTooltip": "Drill down", + "linkUrl": "d/728bf77cc1166d2f3133bf25846876cc/kubernetes-networking-workload?orgId=1&refresh=30s&var-namespace=$namespace&var-type=$type&var-workload=$__cell", + "pattern": "workload", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + }, + { + "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "C", + "step": 10 + }, + { + "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "D", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "E", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "F", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "G", + "step": 10 + }, + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "H", + "step": 10 + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Status", + "type": "table" + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 6, + "panels": [ + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 7, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}} workload {{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Rate of Bytes Received", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 8, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}} workload {{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Rate of Bytes Transmitted", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Average Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 29 + }, + "id": 9, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth HIstory", + "titleSize": "h6", + "type": "row" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 38 + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 38 + }, + "id": 11, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 39 + }, + "id": 12, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 40 + }, + "id": 13, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 40 + }, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Packets", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 40 + }, + "id": 15, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 41 + }, + "id": 16, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 41 + }, + "id": 17, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\", workload_type=\"$type\"}) by (workload))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}workload{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Errors", + "titleSize": "h6", + "type": "row" + } + ], + "refresh": "10s", + "rows": [ + + ], + "schemaVersion": 18, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "kube-system", + "value": "kube-system" + }, + "datasource": "$datasource", + "definition": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "deployment", + "value": "deployment" + }, + "datasource": "$datasource", + "definition": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\"}, workload_type)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "type", + "options": [ + + ], + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=\"$namespace\", workload=~\".+\"}, workload_type)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "resolution", + "options": [ + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": true, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + } + ], + "query": "30s,5m,1h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 2, + "includeAll": false, + "label": null, + "multi": false, + "name": "interval", + "options": [ + { + "selected": true, + "text": "4h", + "value": "4h" + } + ], + "query": "4h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Networking / Namespace (Workload)", + "uid": "bbb2a765a623ae38130206c7d94a160f", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml new file mode 100644 index 0000000000..a4bf29fd11 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/node-cluster-rsrc-use.yaml @@ -0,0 +1,1063 @@ +{{- /* +Generated from 'node-cluster-rsrc-use' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled (or .Values.nodeExporter.enabled .Values.nodeExporter.forceDeployDashboards) }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "node-cluster-rsrc-use" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + node-cluster-rsrc-use.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 1, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "30s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 2, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "((\n instance:node_cpu_utilisation:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n *\n instance:node_num_cpu:sum{job=\"node-exporter\", cluster=\"$cluster\"}\n) != 0 )\n/ scalar(sum(instance:node_num_cpu:sum{job=\"node-exporter\", cluster=\"$cluster\"}))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}} instance {{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Utilisation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "(\n instance:node_load1_per_cpu:ratio{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance:node_load1_per_cpu:ratio{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Saturation (Load1 per CPU)", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "CPU", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "(\n instance:node_memory_utilisation:ratio{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance:node_memory_utilisation:ratio{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Utilisation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 5, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_vmstat_pgmajfault:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Saturation (Major Page Faults)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "rds", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "rds", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Memory", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "alias": "/Receive/", + "stack": "A" + }, + { + "alias": "/Transmit/", + "stack": "B", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_network_receive_bytes_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Receive", + "refId": "A" + }, + { + "expr": "instance:node_network_transmit_bytes_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Transmit", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Utilisation (Bytes Receive/Transmit)", + "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": null, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 7, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "alias": "/ Receive/", + "stack": "A" + }, + { + "alias": "/ Transmit/", + "stack": "B", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_network_receive_drop_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Receive", + "refId": "A" + }, + { + "expr": "instance:node_network_transmit_drop_excluding_lo:rate5m{job=\"node-exporter\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} Transmit", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Saturation (Drops Receive/Transmit)", + "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": null, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Network", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "(\n instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk IO Utilisation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 9, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "(\n instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}\n / scalar(count(instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", cluster=\"$cluster\"}))\n) != 0\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}} {{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk IO Saturation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Disk IO", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum without (device) (\n max without (fstype, mountpoint) ((\n node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"}\n -\n node_filesystem_avail_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"}\n ) != 0)\n)\n/ scalar(sum(max without (fstype, mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", mountpoint!=\"\", cluster=\"$cluster\"})))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Space Utilisation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Disk Space", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(node_time_seconds, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Node Exporter / USE Method / Cluster", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/node-rsrc-use.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/node-rsrc-use.yaml new file mode 100644 index 0000000000..9c1a8fe59f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/node-rsrc-use.yaml @@ -0,0 +1,1089 @@ +{{- /* +Generated from 'node-rsrc-use' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled (or .Values.nodeExporter.enabled .Values.nodeExporter.forceDeployDashboards) }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "node-rsrc-use" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + node-rsrc-use.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 1, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "30s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 2, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_cpu_utilisation:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Utilisation", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Utilisation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_load1_per_cpu:ratio{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Saturation", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Saturation (Load1 per CPU)", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "CPU", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_memory_utilisation:ratio{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Utilisation", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Utilisation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 5, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_vmstat_pgmajfault:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Major page Faults", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Saturation (Major Page Faults)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "rds", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "rds", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Memory", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "alias": "/Receive/", + "stack": "A" + }, + { + "alias": "/Transmit/", + "stack": "B", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_network_receive_bytes_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Receive", + "refId": "A" + }, + { + "expr": "instance:node_network_transmit_bytes_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Transmit", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Utilisation (Bytes Receive/Transmit)", + "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": null, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 7, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "alias": "/ Receive/", + "stack": "A" + }, + { + "alias": "/ Transmit/", + "stack": "B", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance:node_network_receive_drop_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Receive", + "refId": "A" + }, + { + "expr": "instance:node_network_transmit_drop_excluding_lo:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Transmit", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Saturation (Drops Receive/Transmit)", + "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": null, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Network", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance_device:node_disk_io_time_seconds:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk IO Utilisation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 9, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\"node-exporter\", instance=\"$instance\", cluster=\"$cluster\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk IO Saturation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Disk IO", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "fillGradient": 0, + "gridPos": { + + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(1 -\n (\n max without (mountpoint, fstype) (node_filesystem_avail_bytes{job=\"node-exporter\", fstype!=\"\", instance=\"$instance\", cluster=\"$cluster\"})\n /\n max without (mountpoint, fstype) (node_filesystem_size_bytes{job=\"node-exporter\", fstype!=\"\", instance=\"$instance\", cluster=\"$cluster\"})\n ) != 0\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Space Utilisation", + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Disk Space", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(node_time_seconds, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(node_exporter_build_info{job=\"node-exporter\", cluster=\"$cluster\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Node Exporter / USE Method / Node", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/nodes-darwin.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/nodes-darwin.yaml new file mode 100644 index 0000000000..562802fa07 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/nodes-darwin.yaml @@ -0,0 +1,1073 @@ +{{- /* +Generated from 'nodes-darwin' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled (and (or .Values.nodeExporter.enabled .Values.nodeExporter.forceDeployDashboards) .Values.nodeExporter.operatingSystems.darwin.enabled) }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "nodes-darwin" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + nodes-darwin.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 1, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "30s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 2, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "(\n (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode=~\"idle|iowait|steal\", instance=\"$instance\"}[$__rate_interval])))\n/ ignoring(cpu) group_left\n count without (cpu, mode) (node_cpu_seconds_total{job=\"node-exporter\", mode=\"idle\", instance=\"$instance\"})\n)\n", + "format": "time_series", + "intervalFactor": 5, + "legendFormat": "{{`{{`}}cpu{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "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": "percentunit", + "label": null, + "logBase": 1, + "max": 1, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 0, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_load1{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "1m load average", + "refId": "A" + }, + { + "expr": "node_load5{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "5m load average", + "refId": "B" + }, + { + "expr": "node_load15{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "15m load average", + "refId": "C" + }, + { + "expr": "count(node_cpu_seconds_total{job=\"node-exporter\", instance=\"$instance\", mode=\"idle\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "logical cores", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Load Average", + "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": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "CPU", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 9, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Physical Memory", + "refId": "A" + }, + { + "expr": "(\n node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\"} -\n node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\"} +\n node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\"} +\n node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\"}\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Memory Used", + "refId": "B" + }, + { + "expr": "(\n node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\"} -\n node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\"}\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "App Memory", + "refId": "C" + }, + { + "expr": "node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Wired Memory", + "refId": "D" + }, + { + "expr": "node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Compressed", + "refId": "E" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)" + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 80 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + } + }, + "gridPos": { + + }, + "id": 5, + "span": 3, + "targets": [ + { + "expr": "(\n (\n avg(node_memory_internal_bytes{job=\"node-exporter\", instance=\"$instance\"}) -\n avg(node_memory_purgeable_bytes{job=\"node-exporter\", instance=\"$instance\"}) +\n avg(node_memory_wired_bytes{job=\"node-exporter\", instance=\"$instance\"}) +\n avg(node_memory_compressed_bytes{job=\"node-exporter\", instance=\"$instance\"})\n ) /\n avg(node_memory_total_bytes{job=\"node-exporter\", instance=\"$instance\"})\n)\n*\n100\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "" + } + ], + "title": "Memory Usage", + "transparent": false, + "type": "gauge" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Memory", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 0, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "alias": "/ read| written/", + "yaxis": 1 + }, + { + "alias": "/ io time/", + "yaxis": 2 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(node_disk_read_bytes_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}} read", + "refId": "A" + }, + { + "expr": "rate(node_disk_written_bytes_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}} written", + "refId": "B" + }, + { + "expr": "rate(node_disk_io_time_seconds_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}} io time", + "refId": "C" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { + + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "yellow", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Mounted on" + }, + "properties": [ + { + "id": "custom.width", + "value": 260 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Size" + }, + "properties": [ + { + "id": "custom.width", + "value": 93 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used" + }, + "properties": [ + { + "id": "custom.width", + "value": 72 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Available" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used, %" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + }, + { + "id": "custom.displayMode", + "value": "gradient-gauge" + }, + { + "id": "max", + "value": 1 + }, + { + "id": "min", + "value": 0 + } + ] + } + ] + }, + "gridPos": { + + }, + "id": 7, + "span": 6, + "targets": [ + { + "expr": "max by (mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", instance=\"$instance\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "" + }, + { + "expr": "max by (mountpoint) (node_filesystem_avail_bytes{job=\"node-exporter\", instance=\"$instance\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "" + } + ], + "title": "Disk Space Usage", + "transformations": [ + { + "id": "groupBy", + "options": { + "fields": { + "Value #A": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "Value #B": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "mountpoint": { + "aggregations": [ + + ], + "operation": "groupby" + } + } + } + }, + { + "id": "merge", + "options": { + + } + }, + { + "id": "calculateField", + "options": { + "alias": "Used", + "binary": { + "left": "Value #A (lastNotNull)", + "operator": "-", + "reducer": "sum", + "right": "Value #B (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "calculateField", + "options": { + "alias": "Used, %", + "binary": { + "left": "Used", + "operator": "/", + "reducer": "sum", + "right": "Value #A (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + + }, + "indexByName": { + + }, + "renameByName": { + "Value #A (lastNotNull)": "Size", + "Value #B (lastNotNull)": "Available", + "mountpoint": "Mounted on" + } + } + }, + { + "id": "sortBy", + "options": { + "fields": { + + }, + "sort": [ + { + "field": "Mounted on" + } + ] + } + } + ], + "transparent": false, + "type": "table" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Disk", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Network received (bits/s)", + "fill": 0, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(node_network_receive_bytes_total{job=\"node-exporter\", instance=\"$instance\", device!=\"lo\"}[$__rate_interval]) * 8", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Received", + "tooltip": { + "shared": true, + "sort": 0, + "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": "bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Network transmitted (bits/s)", + "fill": 0, + "fillGradient": 0, + "gridPos": { + + }, + "id": 9, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(node_network_transmit_bytes_total{job=\"node-exporter\", instance=\"$instance\", device!=\"lo\"}[$__rate_interval]) * 8", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Transmitted", + "tooltip": { + "shared": true, + "sort": 0, + "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": "bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Network", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(node_uname_info{job=\"node-exporter\", sysname=\"Darwin\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 0, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Node Exporter / MacOS", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/nodes.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/nodes.yaml new file mode 100644 index 0000000000..08e567b2f5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/nodes.yaml @@ -0,0 +1,1066 @@ +{{- /* +Generated from 'nodes' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled (and (or .Values.nodeExporter.enabled .Values.nodeExporter.forceDeployDashboards) .Values.nodeExporter.operatingSystems.linux.enabled) }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "nodes" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + nodes.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 1, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "30s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 2, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "(\n (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode=~\"idle|iowait|steal\", instance=\"$instance\"}[$__rate_interval])))\n/ ignoring(cpu) group_left\n count without (cpu, mode) (node_cpu_seconds_total{job=\"node-exporter\", mode=\"idle\", instance=\"$instance\"})\n)\n", + "format": "time_series", + "intervalFactor": 5, + "legendFormat": "{{`{{`}}cpu{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "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": "percentunit", + "label": null, + "logBase": 1, + "max": 1, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 0, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_load1{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "1m load average", + "refId": "A" + }, + { + "expr": "node_load5{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "5m load average", + "refId": "B" + }, + { + "expr": "node_load15{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "15m load average", + "refId": "C" + }, + { + "expr": "count(node_cpu_seconds_total{job=\"node-exporter\", instance=\"$instance\", mode=\"idle\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "logical cores", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Load Average", + "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": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "CPU", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 9, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "(\n node_memory_MemTotal_bytes{job=\"node-exporter\", instance=\"$instance\"}\n-\n node_memory_MemFree_bytes{job=\"node-exporter\", instance=\"$instance\"}\n-\n node_memory_Buffers_bytes{job=\"node-exporter\", instance=\"$instance\"}\n-\n node_memory_Cached_bytes{job=\"node-exporter\", instance=\"$instance\"}\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "memory used", + "refId": "A" + }, + { + "expr": "node_memory_Buffers_bytes{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "memory buffers", + "refId": "B" + }, + { + "expr": "node_memory_Cached_bytes{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "memory cached", + "refId": "C" + }, + { + "expr": "node_memory_MemFree_bytes{job=\"node-exporter\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "memory free", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)" + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 80 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + } + }, + "gridPos": { + + }, + "id": 5, + "span": 3, + "targets": [ + { + "expr": "100 -\n(\n avg(node_memory_MemAvailable_bytes{job=\"node-exporter\", instance=\"$instance\"}) /\n avg(node_memory_MemTotal_bytes{job=\"node-exporter\", instance=\"$instance\"})\n* 100\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "" + } + ], + "title": "Memory Usage", + "transparent": false, + "type": "gauge" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Memory", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 0, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "alias": "/ read| written/", + "yaxis": 1 + }, + { + "alias": "/ io time/", + "yaxis": 2 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(node_disk_read_bytes_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}} read", + "refId": "A" + }, + { + "expr": "rate(node_disk_written_bytes_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}} written", + "refId": "B" + }, + { + "expr": "rate(node_disk_io_time_seconds_total{job=\"node-exporter\", instance=\"$instance\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}} io time", + "refId": "C" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk I/O", + "tooltip": { + "shared": true, + "sort": 0, + "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": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { + + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "yellow", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Mounted on" + }, + "properties": [ + { + "id": "custom.width", + "value": 260 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Size" + }, + "properties": [ + { + "id": "custom.width", + "value": 93 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used" + }, + "properties": [ + { + "id": "custom.width", + "value": 72 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Available" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used, %" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + }, + { + "id": "custom.displayMode", + "value": "gradient-gauge" + }, + { + "id": "max", + "value": 1 + }, + { + "id": "min", + "value": 0 + } + ] + } + ] + }, + "gridPos": { + + }, + "id": 7, + "span": 6, + "targets": [ + { + "expr": "max by (mountpoint) (node_filesystem_size_bytes{job=\"node-exporter\", instance=\"$instance\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "" + }, + { + "expr": "max by (mountpoint) (node_filesystem_avail_bytes{job=\"node-exporter\", instance=\"$instance\", fstype!=\"\", mountpoint!=\"\"})\n", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "" + } + ], + "title": "Disk Space Usage", + "transformations": [ + { + "id": "groupBy", + "options": { + "fields": { + "Value #A": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "Value #B": { + "aggregations": [ + "lastNotNull" + ], + "operation": "aggregate" + }, + "mountpoint": { + "aggregations": [ + + ], + "operation": "groupby" + } + } + } + }, + { + "id": "merge", + "options": { + + } + }, + { + "id": "calculateField", + "options": { + "alias": "Used", + "binary": { + "left": "Value #A (lastNotNull)", + "operator": "-", + "reducer": "sum", + "right": "Value #B (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "calculateField", + "options": { + "alias": "Used, %", + "binary": { + "left": "Used", + "operator": "/", + "reducer": "sum", + "right": "Value #A (lastNotNull)" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + + }, + "indexByName": { + + }, + "renameByName": { + "Value #A (lastNotNull)": "Size", + "Value #B (lastNotNull)": "Available", + "mountpoint": "Mounted on" + } + } + }, + { + "id": "sortBy", + "options": { + "fields": { + + }, + "sort": [ + { + "field": "Mounted on" + } + ] + } + } + ], + "transparent": false, + "type": "table" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Disk", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Network received (bits/s)", + "fill": 0, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(node_network_receive_bytes_total{job=\"node-exporter\", instance=\"$instance\", device!=\"lo\"}[$__rate_interval]) * 8", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Received", + "tooltip": { + "shared": true, + "sort": 0, + "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": "bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "Network transmitted (bits/s)", + "fill": 0, + "fillGradient": 0, + "gridPos": { + + }, + "id": 9, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(node_network_transmit_bytes_total{job=\"node-exporter\", instance=\"$instance\", device!=\"lo\"}[$__rate_interval]) * 8", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}device{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Transmitted", + "tooltip": { + "shared": true, + "sort": 0, + "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": "bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Network", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "node-exporter-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(node_uname_info{job=\"node-exporter\", sysname!=\"Darwin\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 0, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Node Exporter / Nodes", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml new file mode 100644 index 0000000000..0e12e0a7bb --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/persistentvolumesusage.yaml @@ -0,0 +1,587 @@ +{{- /* +Generated from 'persistentvolumesusage' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "persistentvolumesusage" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + persistentvolumesusage.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 9, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "(\n sum without(instance, node) (topk(1, (kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n -\n sum without(instance, node) (topk(1, (kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n)\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Used Space", + "refId": "A" + }, + { + "expr": "sum without(instance, node) (topk(1, (kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Free Space", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Volume Space Usage", + "tooltip": { + "shared": false, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "$datasource", + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + + }, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "rightSide": true + }, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "max without(instance,node) (\n(\n topk(1, kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n -\n topk(1, kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n)\n/\ntopk(1, kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n* 100)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "80, 90", + "title": "Volume Space Usage", + "tooltip": { + "shared": false + }, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 9, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Used inodes", + "refId": "A" + }, + { + "expr": "(\n sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n -\n sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})))\n)\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": " Free inodes", + "refId": "B" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Volume inodes Usage", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "$datasource", + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + + }, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "rightSide": true + }, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "max without(instance,node) (\ntopk(1, kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n/\ntopk(1, kubelet_volume_stats_inodes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n* 100)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "80, 90", + "title": "Volume inodes Usage", + "tooltip": { + "shared": false + }, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(kubelet_volume_stats_capacity_bytes{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "Namespace", + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\"}, namespace)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "PersistentVolumeClaim", + "multi": false, + "name": "volume", + "options": [ + + ], + "query": "label_values(kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics\", namespace=\"$namespace\"}, persistentvolumeclaim)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-7d", + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Persistent Volumes", + "uid": "919b92a8e8041bd567af9edab12c840c", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/pod-total.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/pod-total.yaml new file mode 100644 index 0000000000..b174822a5a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/pod-total.yaml @@ -0,0 +1,1228 @@ +{{- /* +Generated from 'pod-total' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "pod-total" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + pod-total.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "panels": [ + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Current Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "decimals": 0, + "format": "time_series", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 1 + }, + "height": 9, + "id": 3, + "interval": null, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "minSpan": 12, + "nullPointMode": "connected", + "nullText": null, + "options": { + "fieldOptions": { + "calcs": [ + "last" + ], + "defaults": { + "max": 10000000000, + "min": 0, + "title": "$namespace: $pod", + "unit": "Bps" + }, + "mappings": [ + + ], + "override": { + + }, + "thresholds": [ + { + "color": "dark-green", + "index": 0, + "value": null + }, + { + "color": "dark-yellow", + "index": 1, + "value": 5000000000 + }, + { + "color": "dark-red", + "index": 2, + "value": 7000000000 + } + ], + "values": false + } + }, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 12, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution]))", + "format": "time_series", + "instant": null, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Received", + "type": "gauge", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "decimals": 0, + "format": "time_series", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 1 + }, + "height": 9, + "id": 4, + "interval": null, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "minSpan": 12, + "nullPointMode": "connected", + "nullText": null, + "options": { + "fieldOptions": { + "calcs": [ + "last" + ], + "defaults": { + "max": 10000000000, + "min": 0, + "title": "$namespace: $pod", + "unit": "Bps" + }, + "mappings": [ + + ], + "override": { + + }, + "thresholds": [ + { + "color": "dark-green", + "index": 0, + "value": null + }, + { + "color": "dark-yellow", + "index": 1, + "value": 5000000000 + }, + { + "color": "dark-red", + "index": 2, + "value": 7000000000 + } + ], + "values": false + } + }, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 12, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution]))", + "format": "time_series", + "instant": null, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Transmitted", + "type": "gauge", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 5, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 11 + }, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 11 + }, + "id": 7, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_transmit_bytes_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 8, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 9, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_transmit_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Packets", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 11, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 32 + }, + "id": 12, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_receive_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 32 + }, + "id": 13, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_network_transmit_packets_dropped_total{cluster=\"$cluster\",namespace=~\"$namespace\", pod=~\"$pod\"}[$interval:$resolution])) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Errors", + "titleSize": "h6", + "type": "row" + } + ], + "refresh": "10s", + "rows": [ + + ], + "schemaVersion": 18, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".+", + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "kube-system", + "value": "kube-system" + }, + "datasource": "$datasource", + "definition": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".+", + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "definition": "label_values(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}, pod)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "pod", + "options": [ + + ], + "query": "label_values(container_network_receive_packets_total{cluster=\"$cluster\",namespace=~\"$namespace\"}, pod)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "resolution", + "options": [ + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": true, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + } + ], + "query": "30s,5m,1h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 2, + "includeAll": false, + "label": null, + "multi": false, + "name": "interval", + "options": [ + { + "selected": true, + "text": "4h", + "value": "4h" + } + ], + "query": "4h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Networking / Pod", + "uid": "7a18067ce943a40ae25454675c19ff5c", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml new file mode 100644 index 0000000000..5fc57e1b28 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/prometheus-remote-write.yaml @@ -0,0 +1,1674 @@ +{{- /* +Generated from 'prometheus-remote-write' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled .Values.prometheus.prometheusSpec.remoteWriteDashboards }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "prometheus-remote-write" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + prometheus-remote-write.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "60s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 2, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(\n prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~\"$cluster\", instance=~\"$instance\"} \n- \n ignoring(remote_name, url) group_right(instance) (prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~\"$cluster\", instance=~\"$instance\"} != 0)\n)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Highest Timestamp In vs. Highest Timestamp Sent", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "clamp_min(\n rate(prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) \n- \n ignoring (remote_name, url) group_right(instance) rate(prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])\n, 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate[5m]", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Timestamps", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(\n prometheus_remote_storage_samples_in_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])\n- \n ignoring(remote_name, url) group_right(instance) (rate(prometheus_remote_storage_succeeded_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]))\n- \n (rate(prometheus_remote_storage_dropped_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_dropped_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate, in vs. succeeded or dropped [5m]", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Samples", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 5, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "minSpan": 6, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_remote_storage_shards{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Shards", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_remote_storage_shards_max{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Max Shards", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 7, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_remote_storage_shards_min{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Min Shards", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_remote_storage_shards_desired{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Desired Shards", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Shards", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 9, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_remote_storage_shard_capacity{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Shard Capacity", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_remote_storage_pending_samples{cluster=~\"$cluster\", instance=~\"$instance\"} or prometheus_remote_storage_samples_pending{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Pending Samples", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Shard Details", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 11, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_wal_segment_current{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "TSDB Current Segment", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 12, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_wal_watcher_current_segment{cluster=~\"$cluster\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}consumer{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Remote Write Current Segment", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Segments", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 13, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_remote_storage_dropped_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_dropped_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Dropped Samples", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_remote_storage_failed_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Failed Samples", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 15, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_remote_storage_retried_samples_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m]) or rate(prometheus_remote_storage_samples_retried_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Retried Samples", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 16, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 3, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_remote_storage_enqueue_retries_total{cluster=~\"$cluster\", instance=~\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}}:{{`{{`}}instance{{`}}`}} {{`{{`}}remote_name{{`}}`}}:{{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Enqueue Retries", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Misc. Rates", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "prometheus-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "value": { + "selected": true, + "text": "All", + "value": "$__all" + } + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": true, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(kube_pod_container_info{image=~\".*prometheus.*\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "value": { + "selected": true, + "text": "All", + "value": "$__all" + } + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(prometheus_build_info{cluster=~\"$cluster\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "url", + "options": [ + + ], + "query": "label_values(prometheus_remote_storage_shards{cluster=~\"$cluster\", instance=~\"$instance\"}, url)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-6h", + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Prometheus / Remote Write", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/prometheus.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/prometheus.yaml new file mode 100644 index 0000000000..b1f9d73332 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/prometheus.yaml @@ -0,0 +1,1235 @@ +{{- /* +Generated from 'prometheus' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "prometheus" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + prometheus.json: |- + { + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + + ], + "refresh": "60s", + "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": 12, + "stack": false, + "steppedLine": false, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "Count", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #A", + "thresholds": [ + + ], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Uptime", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "Value #B", + "thresholds": [ + + ], + "type": "number", + "unit": "s" + }, + { + "alias": "Instance", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "instance", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Job", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "job", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "Version", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Drill down", + "linkUrl": "", + "pattern": "version", + "thresholds": [ + + ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + + ], + "type": "string", + "unit": "short" + } + ], + "targets": [ + { + "expr": "count by (job, instance, version) (prometheus_build_info{job=~\"$job\", instance=~\"$instance\"})", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 10 + }, + { + "expr": "max by (job, instance) (time() - process_start_time_seconds{job=~\"$job\", instance=~\"$instance\"})", + "format": "table", + "instant": true, + "intervalFactor": 2, + "legendFormat": "", + "refId": "B", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Prometheus Stats", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "transform": "table", + "type": "table", + "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": "Prometheus Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "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(rate(prometheus_target_sync_length_seconds_sum{job=~\"$job\",instance=~\"$instance\"}[5m])) by (scrape_job) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}scrape_job{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Target Sync", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "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(prometheus_sd_discovered_targets{job=~\"$job\",instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Targets", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Targets", + "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": "Discovery", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "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": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_target_interval_length_seconds_sum{job=~\"$job\",instance=~\"$instance\"}[5m]) / rate(prometheus_target_interval_length_seconds_count{job=~\"$job\",instance=~\"$instance\"}[5m]) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}interval{{`}}`}} configured", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Scrape Interval Duration", + "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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "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": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (job) (rate(prometheus_target_scrapes_exceeded_body_size_limit_total[1m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "exceeded body size limit: {{`{{`}}job{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum by (job) (rate(prometheus_target_scrapes_exceeded_sample_limit_total[1m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "exceeded sample limit: {{`{{`}}job{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum by (job) (rate(prometheus_target_scrapes_sample_duplicate_timestamp_total[1m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "duplicate timestamp: {{`{{`}}job{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum by (job) (rate(prometheus_target_scrapes_sample_out_of_bounds_total[1m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "out of bounds: {{`{{`}}job{{`}}`}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum by (job) (rate(prometheus_target_scrapes_sample_out_of_order_total[1m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "out of order: {{`{{`}}job{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Scrape failures", + "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": 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": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_samples_appended_total{job=~\"$job\",instance=~\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}job{{`}}`}} {{`{{`}}instance{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Appended Samples", + "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": "Retrieval", + "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": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_series{job=~\"$job\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}job{{`}}`}} {{`{{`}}instance{{`}}`}} head series", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Head 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": 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": "prometheus_tsdb_head_chunks{job=~\"$job\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}job{{`}}`}} {{`{{`}}instance{{`}}`}} head chunks", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Head Chunks", + "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": "Storage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "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": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_engine_query_duration_seconds_count{job=~\"$job\",instance=~\"$instance\",slice=\"inner_eval\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}job{{`}}`}} {{`{{`}}instance{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Query 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 + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 10, + "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": "max by (slice) (prometheus_engine_query_duration_seconds{quantile=\"0.9\",job=~\"$job\",instance=~\"$instance\"}) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}slice{{`}}`}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Stage Duration", + "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": "Query", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "prometheus-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": ".+", + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": "job", + "multi": true, + "name": "job", + "options": [ + + ], + "query": "label_values(prometheus_build_info{job=\"prometheus-k8s\",namespace=\"monitoring\"}, job)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".+", + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": "instance", + "multi": true, + "name": "instance", + "options": [ + + ], + "query": "label_values(prometheus_build_info{job=~\"$job\"}, instance)", + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Prometheus / Overview", + "uid": "", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/proxy.yaml new file mode 100644 index 0000000000..69b8abcd60 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/proxy.yaml @@ -0,0 +1,1276 @@ +{{- /* +Generated from 'proxy' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +{{- if (include "exporter.kubeProxy.enabled" .)}} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "proxy" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + proxy.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + + }, + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "rightSide": true + }, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + {{- if .Values.k3sServer.enabled }} + "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", metrics_path=\"/metrics\"})", + {{- else }} + "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\"})", + {{- end }} + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "Up", + "tooltip": { + "shared": false + }, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "min" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 5, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(kubeproxy_sync_proxy_rules_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "rate", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rules Sync Rate", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 5, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99,rate(kubeproxy_sync_proxy_rules_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rule Sync Latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(kubeproxy_network_programming_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "rate", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Programming Rate", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(kubeproxy_network_programming_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Programming Latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "2xx", + "refId": "A" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "3xx", + "refId": "B" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "4xx", + "refId": "C" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "5xx", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Kube API Request Rate", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 8, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\",instance=~\"$instance\",verb=\"POST\"}[$__rate_interval])) by (verb, url, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Post Request Latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 9, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, url, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Get Request Latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": false, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 11, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU usage", + "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": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 12, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_goroutines{cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Goroutines", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubeProxy.jobName" . }}\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubeProxy.jobName" . }}\", cluster=\"$cluster\", job=\"{{ include "exporter.kubeProxy.jobName" . }}\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Proxy", + "uid": "632e265de029684c40b21cb76bca4f94", + "version": 0 + } +{{- end }}{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/scheduler.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/scheduler.yaml new file mode 100644 index 0000000000..4d439c8980 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/scheduler.yaml @@ -0,0 +1,1118 @@ +{{- /* +Generated from 'scheduler' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +{{- if (include "exporter.kubeScheduler.enabled" .)}} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "scheduler" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + scheduler.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "$datasource", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + + }, + "id": 2, + "interval": "1m", + "legend": { + "alignAsTable": true, + "rightSide": true + }, + "links": [ + + ], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + {{- if .Values.k3sServer.enabled }} + "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", metrics_path=\"/metrics\"})", + {{- else }} + "expr": "sum(up{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\"})", + {{- end }} + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "Up", + "tooltip": { + "shared": false + }, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "min" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 3, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 5, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(scheduler_e2e_scheduling_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} e2e", + "refId": "A" + }, + { + "expr": "sum(rate(scheduler_binding_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} binding", + "refId": "B" + }, + { + "expr": "sum(rate(scheduler_scheduling_algorithm_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} scheduling algorithm", + "refId": "C" + }, + { + "expr": "sum(rate(scheduler_volume_scheduling_duration_seconds_count{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} volume", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Scheduling Rate", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 4, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 5, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} e2e", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(scheduler_binding_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} binding", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} scheduling algorithm", + "refId": "C" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(scheduler_volume_scheduling_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}[$__rate_interval])) by (cluster, instance, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}cluster{{`}}`}} {{`{{`}}instance{{`}}`}} volume", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Scheduling latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 5, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\",code=~\"2..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "2xx", + "refId": "A" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\",code=~\"3..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "3xx", + "refId": "B" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\",code=~\"4..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "4xx", + "refId": "C" + }, + { + "expr": "sum(rate(rest_client_requests_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\",code=~\"5..\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "5xx", + "refId": "D" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Kube API Request Rate", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 6, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 8, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\", verb=\"POST\"}[$__rate_interval])) by (verb, url, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Post Request Latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 7, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\", verb=\"GET\"}[$__rate_interval])) by (verb, url, le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}verb{{`}}`}} {{`{{`}}url{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Get Request Latency 99th Quantile", + "tooltip": { + "shared": false, + "sort": 0, + "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": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 8, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": false, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 9, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", instance=~\"$instance\"}[$__rate_interval])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU usage", + "tooltip": { + "shared": false, + "sort": 0, + "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": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + + }, + "id": 10, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_goroutines{cluster=\"$cluster\", job=\"{{ include "exporter.kubeScheduler.jobName" . }}\",instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{`{{`}}instance{{`}}`}}", + "refId": "A" + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Goroutines", + "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 + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubeScheduler.jobName" . }}\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "instance", + "options": [ + + ], + "query": "label_values(up{job=\"{{ include "exporter.kubeScheduler.jobName" . }}\", cluster=\"$cluster\"}, instance)", + "refresh": 2, + "regex": "", + "sort": 1, + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Scheduler", + "uid": "2e6b6a3b4bddf1427b3a55aa1311c656", + "version": 0 + } +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/workload-total.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/workload-total.yaml new file mode 100644 index 0000000000..8784c7116c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/dashboards-1.14/workload-total.yaml @@ -0,0 +1,1438 @@ +{{- /* +Generated from 'workload-total' from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/b5b59bc0b45508b85647eb7a84b96dc167be15f1/manifests/grafana-dashboardDefinitions.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (or .Values.grafana.enabled .Values.grafana.forceDeployDashboards) (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "workload-total" | trunc 63 | trimSuffix "-" }} + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: {{ ternary $.Values.grafana.sidecar.dashboards.labelValue "1" (not (empty $.Values.grafana.sidecar.dashboards.labelValue)) | quote }} + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: + workload-total.json: |- + { + "__inputs": [ + + ], + "__requires": [ + + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [ + + ], + "panels": [ + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Current Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}} pod {{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Received", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}} pod {{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Current Rate of Bytes Transmitted", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 5, + "panels": [ + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 11 + }, + "id": 6, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(avg(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}} pod {{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Rate of Bytes Received", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 11 + }, + "id": 7, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [ + + ], + "minSpan": 24, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 24, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(avg(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}} pod {{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Average Rate of Bytes Transmitted", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Average Bandwidth", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 11 + }, + "id": 8, + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Bandwidth HIstory", + "titleSize": "h6", + "type": "row" + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 9, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Receive Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_bytes_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Transmit Bandwidth", + "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": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 11, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 22 + }, + "id": 12, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 22 + }, + "id": 13, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Packets", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": true, + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 14, + "panels": [ + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 23 + }, + "id": 15, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_receive_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Received Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + }, + { + "aliasColors": { + + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 23 + }, + "id": 16, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + + ], + "minSpan": 12, + "nullPointMode": "connected", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + + ], + "spaceLength": 10, + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum(irate(container_network_transmit_packets_dropped_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\",namespace=~\"$namespace\"}[$interval:$resolution])\n* on (namespace,pod)\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\", workload_type=\"$type\"}) by (pod))\n", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{`{{`}}pod{{`}}`}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ + + ], + "timeFrom": null, + "timeShift": null, + "title": "Rate of Transmitted Packets Dropped", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + + ] + }, + "yaxes": [ + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "pps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Errors", + "titleSize": "h6", + "type": "row" + } + ], + "refresh": "10s", + "rows": [ + + ], + "schemaVersion": 18, + "style": "dark", + "tags": [ + "kubernetes-mixin" + ], + "templating": { + "list": [ + { + "current": { + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ + + ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + + }, + "datasource": "$datasource", + "hide": {{ if .Values.grafana.sidecar.dashboards.multicluster.global.enabled }}0{{ else }}2{{ end }}, + "includeAll": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [ + + ], + "query": "label_values(kube_pod_info{job=\"kube-state-metrics\"}, cluster)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".+", + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "kube-system", + "value": "kube-system" + }, + "datasource": "$datasource", + "definition": "label_values(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\"}, namespace)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "namespace", + "options": [ + + ], + "query": "label_values(container_network_receive_packets_total{job=\"{{ include "exporter.kubelet.jobName" . }}\", metrics_path=\"/metrics/cadvisor\", cluster=\"$cluster\"}, namespace)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "", + "value": "" + }, + "datasource": "$datasource", + "definition": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\"}, workload)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "workload", + "options": [ + + ], + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\"}, workload)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "deployment", + "value": "deployment" + }, + "datasource": "$datasource", + "definition": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\"}, workload_type)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "type", + "options": [ + + ], + "query": "label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\"$cluster\",namespace=~\"$namespace\", workload=~\"$workload\"}, workload_type)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "resolution", + "options": [ + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": true, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + } + ], + "query": "30s,5m,1h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "useTags": false + }, + { + "allValue": null, + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "datasource": "$datasource", + "hide": 2, + "includeAll": false, + "label": null, + "multi": false, + "name": "interval", + "options": [ + { + "selected": true, + "text": "4h", + "value": "4h" + } + ], + "query": "4h", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [ + + ], + "tagsQuery": "", + "type": "interval", + "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": "{{ .Values.grafana.defaultDashboardsTimezone }}", + "title": "Kubernetes / Networking / Workload", + "uid": "728bf77cc1166d2f3133bf25846876cc", + "version": 0 + } +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/namespaces.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/namespaces.yaml new file mode 100644 index 0000000000..39ed210ed4 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/grafana/namespaces.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled (not .Values.grafana.defaultDashboards.useExistingNamespace) }} +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Values.grafana.defaultDashboards.namespace }} + labels: + name: {{ .Values.grafana.defaultDashboards.namespace }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + annotations: +{{- if not .Values.grafana.defaultDashboards.cleanupOnUninstall }} + helm.sh/resource-policy: "keep" +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/_prometheus-operator.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/_prometheus-operator.tpl new file mode 100644 index 0000000000..6ae9dc72e6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/_prometheus-operator.tpl @@ -0,0 +1,7 @@ +{{/* Generate basic labels for prometheus-operator */}} +{{- define "kube-prometheus-stack.prometheus-operator.labels" }} +{{- include "kube-prometheus-stack.labels" . }} +app: {{ template "kube-prometheus-stack.name" . }}-operator +app.kubernetes.io/name: {{ template "kube-prometheus-stack.name" . }}-prometheus-operator +app.kubernetes.io/component: prometheus-operator +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl new file mode 100644 index 0000000000..f419caf54b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/_prometheus-operator-webhook.tpl @@ -0,0 +1,6 @@ +{{/* Generate basic labels for prometheus-operator-webhook */}} +{{- define "kube-prometheus-stack.prometheus-operator-webhook.labels" }} +{{- include "kube-prometheus-stack.labels" . }} +app.kubernetes.io/name: {{ template "kube-prometheus-stack.name" . }}-prometheus-operator +app.kubernetes.io/component: prometheus-operator-webhook +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml new file mode 100644 index 0000000000..054eac4a77 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/deployment.yaml @@ -0,0 +1,143 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.deployment.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }}-webhook + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 4 }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.labels }} +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.labels | indent 4 }} +{{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.annotations }} + annotations: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.annotations | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.prometheusOperator.admissionWebhooks.deployment.replicas }} + revisionHistoryLimit: {{ .Values.prometheusOperator.admissionWebhooks.deployment.revisionHistoryLimit }} + {{- with .Values.prometheusOperator.admissionWebhooks.deployment.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook + release: {{ $.Release.Name | quote }} + template: + metadata: + labels: + app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 8 }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.podLabels }} +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.podLabels | indent 8 }} +{{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.podAnnotations }} + annotations: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.podAnnotations | indent 8 }} +{{- end }} + spec: + {{- if .Values.prometheusOperator.admissionWebhooks.deployment.priorityClassName }} + priorityClassName: {{ .Values.prometheusOperator.admissionWebhooks.deployment.priorityClassName }} + {{- end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "kube-prometheus-stack.imagePullSecrets" . | indent 8 }} + {{- end }} + containers: + - name: prometheus-operator-admission-webhook + {{- $operatorRegistry := .Values.global.imageRegistry | default .Values.prometheusOperator.admissionWebhooks.deployment.image.registry -}} + {{- if .Values.prometheusOperator.admissionWebhooks.deployment.image.sha }} + image: "{{ $operatorRegistry }}/{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.sha }}" + {{- else }} + image: "{{ $operatorRegistry }}/{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: "{{ .Values.prometheusOperator.admissionWebhooks.deployment.image.pullPolicy }}" + args: + {{- if .Values.prometheusOperator.admissionWebhooks.deployment.logFormat }} + - --log-format={{ .Values.prometheusOperator.admissionWebhooks.deployment.logFormat }} + {{- end }} + {{- if .Values.prometheusOperator.admissionWebhooks.deployment.logLevel }} + - --log-level={{ .Values.prometheusOperator.admissionWebhooks.deployment.logLevel }} + {{- end }} + {{- if .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled }} + - "--web.enable-tls=true" + - "--web.cert-file=/cert/{{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}tls.crt{{ else }}cert{{ end }}" + - "--web.key-file=/cert/{{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}tls.key{{ else }}key{{ end }}" + - "--web.listen-address=:{{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.internalPort }}" + - "--web.tls-min-version={{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.tlsMinVersion }}" + ports: + - containerPort: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.internalPort }} + name: https + {{- else }} + ports: + - containerPort: 8080 + name: http + {{- end }} + {{- if .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /healthz + port: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled | ternary "https" "http" }} + scheme: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled | ternary "HTTPS" "HTTP" }} + initialDelaySeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.prometheusOperator.admissionWebhooks.deployment.readinessProbe.failureThreshold }} + {{- end }} + {{- if .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /healthz + port: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled | ternary "https" "http" }} + scheme: {{ .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled | ternary "HTTPS" "HTTP" }} + initialDelaySeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.prometheusOperator.admissionWebhooks.deployment.livenessProbe.failureThreshold }} + {{- end }} + resources: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.resources | indent 12 }} + securityContext: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.containerSecurityContext | indent 12 }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled }} + volumeMounts: + - name: tls-secret + mountPath: /cert + readOnly: true + volumes: + - name: tls-secret + secret: + defaultMode: 420 + secretName: {{ template "kube-prometheus-stack.fullname" . }}-admission +{{- end }} + {{- with .Values.prometheusOperator.admissionWebhooks.deployment.dnsConfig }} + dnsConfig: +{{ toYaml . | indent 8 }} + {{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.securityContext }} + securityContext: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.securityContext | indent 8 }} +{{- end }} + serviceAccountName: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }}-webhook + automountServiceAccountToken: {{ .Values.prometheusOperator.admissionWebhooks.deployment.automountServiceAccountToken }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.hostNetwork }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet +{{- end }} + {{- with .Values.prometheusOperator.admissionWebhooks.deployment.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.prometheusOperator.admissionWebhooks.deployment.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.prometheusOperator.admissionWebhooks.deployment.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml new file mode 100644 index 0000000000..04458b9675 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/pdb.yaml @@ -0,0 +1,15 @@ +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.podDisruptionBudget -}} +apiVersion: {{ include "kube-prometheus-stack.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }}-webhook + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook + release: {{ $.Release.Name | quote }} +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.podDisruptionBudget | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/service.yaml new file mode 100644 index 0000000000..6de9cbb71d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/service.yaml @@ -0,0 +1,62 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.deployment.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }}-webhook + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 4 }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.labels }} +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.service.labels | indent 4 }} +{{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.annotations }} + annotations: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.service.annotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.clusterIP }} + clusterIP: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.clusterIP }} +{{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.ipDualStack.ipFamilyPolicy }} +{{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.externalIPs }} + externalIPs: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.deployment.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.loadBalancerIP }} +{{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.deployment.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.prometheusOperator.admissionWebhooks.deployment.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if ne .Values.prometheusOperator.admissionWebhooks.deployment.service.type "ClusterIP" }} + externalTrafficPolicy: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.externalTrafficPolicy }} +{{- end }} + ports: + {{- if not .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled }} + - name: http + {{- if eq .Values.prometheusOperator.admissionWebhooks.deployment.service.type "NodePort" }} + nodePort: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.nodePort }} + {{- end }} + port: 8080 + targetPort: http + {{- end }} + {{- if .Values.prometheusOperator.admissionWebhooks.deployment.tls.enabled }} + - name: https + {{- if eq .Values.prometheusOperator.admissionWebhooks.deployment.service.type "NodePort"}} + nodePort: {{ .Values.prometheusOperator.admissionWebhooks.deployment.service.nodePortTls }} + {{- end }} + port: 443 + targetPort: https + {{- end }} + selector: + app: {{ template "kube-prometheus-stack.name" . }}-operator-webhook + release: {{ $.Release.Name | quote }} + type: "{{ .Values.prometheusOperator.admissionWebhooks.deployment.service.type }}" +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml new file mode 100644 index 0000000000..55511da36b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/deployment/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.deployment.enabled }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.prometheusOperator.admissionWebhooks.deployment.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "kube-prometheus-stack.operator.admissionWebhooks.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-operator + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | indent 4 }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml new file mode 100644 index 0000000000..f7543b0f1a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-createSecret.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "cilium") }} +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission-create + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + ## Ensure this is run before the job + helm.sh/hook-weight: "-5" + {{- with .Values.prometheusOperator.admissionWebhooks.annotations }} + {{ toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-create + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +spec: + endpointSelector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-create + {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} + {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} + {{- else }} + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 6 }} + {{- end }} + egress: + {{- if and .Values.prometheusOperator.networkPolicy.cilium .Values.prometheusOperator.networkPolicy.cilium.egress }} + {{ toYaml .Values.prometheusOperator.networkPolicy.cilium.egress | nindent 6 }} + {{- else }} + - toEntities: + - kube-apiserver + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml new file mode 100644 index 0000000000..4e3b0d9225 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/ciliumnetworkpolicy-patchWebhook.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "cilium") }} +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission-patch + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + helm.sh/hook: post-install,post-upgrade + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + ## Ensure this is run before the job + helm.sh/hook-weight: "-5" + {{- with .Values.prometheusOperator.admissionWebhooks.patch.annotations }} + {{ toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +spec: + endpointSelector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch + {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} + {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} + {{- else }} + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 6 }} + {{- end }} + egress: + {{- if and .Values.prometheusOperator.networkPolicy.cilium .Values.prometheusOperator.networkPolicy.cilium.egress }} + {{ toYaml .Values.prometheusOperator.networkPolicy.cilium.egress | nindent 6 }} + {{- else }} + - toEntities: + - kube-apiserver + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml new file mode 100644 index 0000000000..1695490354 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrole.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +rules: + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + - mutatingwebhookconfigurations + verbs: + - get + - update +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.global.rbac.pspEnabled }} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} + - apiGroups: ['policy'] +{{- else }} + - apiGroups: ['extensions'] +{{- end }} + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-prometheus-stack.fullname" . }}-admission +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml new file mode 100644 index 0000000000..4cf1335b22 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kube-prometheus-stack.fullname" . }}-admission +subjects: + - kind: ServiceAccount + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml new file mode 100644 index 0000000000..baed83db48 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-createSecret.yaml @@ -0,0 +1,73 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission-create + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{- with .Values.prometheusOperator.admissionWebhooks.annotations }} +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-create + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +spec: + {{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }} + # Alpha feature since k8s 1.12 + ttlSecondsAfterFinished: 0 + {{- end }} + template: + metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission-create +{{- with .Values.prometheusOperator.admissionWebhooks.patch.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-create + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 8 }} + spec: + {{- if .Values.prometheusOperator.admissionWebhooks.patch.priorityClassName }} + priorityClassName: {{ .Values.prometheusOperator.admissionWebhooks.patch.priorityClassName }} + {{- end }} + containers: + - name: create + {{- $registry := include "monitoring_registry" . | default .Values.prometheusOperator.admissionWebhooks.patch.image.registry -}} + {{- if .Values.prometheusOperator.admissionWebhooks.patch.image.sha }} + image: {{ $registry }}/{{ .Values.prometheusOperator.admissionWebhooks.patch.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.tag }}@sha256:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.sha }} + {{- else }} + image: {{ $registry }}/{{ .Values.prometheusOperator.admissionWebhooks.patch.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.tag }} + {{- end }} + imagePullPolicy: {{ .Values.prometheusOperator.admissionWebhooks.patch.image.pullPolicy }} + args: + - create + - --host={{- include "kube-prometheus-stack.operator.admission-webhook.dnsNames" . | replace "\n" "," }} + - --namespace={{ template "kube-prometheus-stack.namespace" . }} + - --secret-name={{ template "kube-prometheus-stack.fullname" . }}-admission + {{- with .Values.prometheusOperator.admissionWebhooks.createSecretJob }} + securityContext: + {{ toYaml .securityContext | nindent 12 }} + {{- end }} + resources: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.patch.resources | indent 12 }} + restartPolicy: OnFailure + serviceAccountName: {{ template "kube-prometheus-stack.fullname" . }}-admission + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- with .Values.prometheusOperator.admissionWebhooks.patch.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + {{- with .Values.prometheusOperator.admissionWebhooks.patch.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- with .Values.prometheusOperator.admissionWebhooks.patch.tolerations }} +{{ toYaml . | indent 8 }} + {{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.patch.securityContext }} + securityContext: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.patch.securityContext | indent 8 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml new file mode 100644 index 0000000000..5639cc9e80 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/job-patchWebhook.yaml @@ -0,0 +1,74 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission-patch + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{- with .Values.prometheusOperator.admissionWebhooks.patch.annotations }} +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +spec: + {{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }} + # Alpha feature since k8s 1.12 + ttlSecondsAfterFinished: 0 + {{- end }} + template: + metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission-patch +{{- with .Values.prometheusOperator.admissionWebhooks.patch.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 8 }} + spec: + {{- if .Values.prometheusOperator.admissionWebhooks.patch.priorityClassName }} + priorityClassName: {{ .Values.prometheusOperator.admissionWebhooks.patch.priorityClassName }} + {{- end }} + containers: + - name: patch + {{- $registry := include "monitoring_registry" . | default .Values.prometheusOperator.admissionWebhooks.patch.image.registry -}} + {{- if .Values.prometheusOperator.admissionWebhooks.patch.image.sha }} + image: {{ $registry }}/{{ .Values.prometheusOperator.admissionWebhooks.patch.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.tag }}@sha256:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.sha }} + {{- else }} + image: {{ $registry }}/{{ .Values.prometheusOperator.admissionWebhooks.patch.image.repository }}:{{ .Values.prometheusOperator.admissionWebhooks.patch.image.tag }} + {{- end }} + imagePullPolicy: {{ .Values.prometheusOperator.admissionWebhooks.patch.image.pullPolicy }} + args: + - patch + - --webhook-name={{ template "kube-prometheus-stack.fullname" . }}-admission + - --namespace={{ template "kube-prometheus-stack.namespace" . }} + - --secret-name={{ template "kube-prometheus-stack.fullname" . }}-admission + - --patch-failure-policy={{ .Values.prometheusOperator.admissionWebhooks.failurePolicy }} + {{- with .Values.prometheusOperator.admissionWebhooks.patchWebhookJob }} + securityContext: + {{ toYaml .securityContext | nindent 12 }} + {{- end }} + resources: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.patch.resources | indent 12 }} + restartPolicy: OnFailure + serviceAccountName: {{ template "kube-prometheus-stack.fullname" . }}-admission + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- with .Values.prometheusOperator.admissionWebhooks.patch.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + {{- with .Values.prometheusOperator.admissionWebhooks.patch.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- with .Values.prometheusOperator.admissionWebhooks.patch.tolerations }} +{{ toYaml . | indent 8 }} + {{- end }} +{{- if .Values.prometheusOperator.admissionWebhooks.patch.securityContext }} + securityContext: +{{ toYaml .Values.prometheusOperator.admissionWebhooks.patch.securityContext | indent 8 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml new file mode 100644 index 0000000000..864deb52a0 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-createSecret.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "kubernetes") }} +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission-create + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + ## Ensure this is run before the job + "helm.sh/hook-weight": "-5" + {{- with .Values.prometheusOperator.admissionWebhooks.annotations }} + {{ toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-create + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-create + {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} + {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} + {{- else }} + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 6 }} + {{- end }} + egress: + - {} + policyTypes: + - Egress +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml new file mode 100644 index 0000000000..076c467004 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/networkpolicy-patchWebhook.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "kubernetes") }} +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission-patch + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + ## Ensure this is run before the job + "helm.sh/hook-weight": "-5" + {{- with .Values.prometheusOperator.admissionWebhooks.patch.annotations }} + {{ toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +spec: + podSelector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission-patch + {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} + {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} + {{- else }} + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 6 }} + {{- end }} + egress: + - {} + policyTypes: + - Egress +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml new file mode 100644 index 0000000000..92c624001b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/psp.yaml @@ -0,0 +1,47 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{- if .Values.global.rbac.pspAnnotations }} +{{ toYaml .Values.global.rbac.pspAnnotations | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-admission + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" . | nindent 4 }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Permits the container to run with root privileges as well. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml new file mode 100644 index 0000000000..f15abf4395 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/role.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml new file mode 100644 index 0000000000..30bde920b6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/rolebinding.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.global.rbac.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "kube-prometheus-stack.fullname" . }}-admission +subjects: + - kind: ServiceAccount + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml new file mode 100644 index 0000000000..8dab40c609 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/job-patch/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled .Values.prometheusOperator.admissionWebhooks.patch.enabled .Values.prometheusOperator.admissionWebhooks.patch.serviceAccount.create (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +automountServiceAccountToken: {{ .Values.prometheusOperator.admissionWebhooks.patch.serviceAccount.automountServiceAccountToken }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml new file mode 100644 index 0000000000..91d96b3845 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/mutatingWebhookConfiguration.yaml @@ -0,0 +1,81 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission +{{- if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }} + annotations: + certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-admission" (include "kube-prometheus-stack.namespace" .) (include "kube-prometheus-stack.fullname" .) | quote }} + cert-manager.io/inject-ca-from: {{ printf "%s/%s-admission" (include "kube-prometheus-stack.namespace" .) (include "kube-prometheus-stack.fullname" .) | quote }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +webhooks: + - name: prometheusrulemutate.monitoring.coreos.com + {{- if eq .Values.prometheusOperator.admissionWebhooks.failurePolicy "IgnoreOnInstallOnly" }} + failurePolicy: {{ .Release.IsInstall | ternary "Ignore" "Fail" }} + {{- else if .Values.prometheusOperator.admissionWebhooks.failurePolicy }} + failurePolicy: {{ .Values.prometheusOperator.admissionWebhooks.failurePolicy }} + {{- else if .Values.prometheusOperator.admissionWebhooks.patch.enabled }} + failurePolicy: Ignore + {{- else }} + failurePolicy: Fail + {{- end }} + rules: + - apiGroups: + - monitoring.coreos.com + apiVersions: + - "*" + resources: + - prometheusrules + operations: + - CREATE + - UPDATE + clientConfig: + service: + namespace: {{ template "kube-prometheus-stack.namespace" . }} + name: {{ template "kube-prometheus-stack.operator.fullname" $ }}{{ if .Values.prometheusOperator.admissionWebhooks.deployment.enabled }}-webhook{{ end }} + path: /admission-prometheusrules/mutate + {{- if and .Values.prometheusOperator.admissionWebhooks.caBundle (not .Values.prometheusOperator.admissionWebhooks.patch.enabled) (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} + caBundle: {{ .Values.prometheusOperator.admissionWebhooks.caBundle }} + {{- end }} + timeoutSeconds: {{ .Values.prometheusOperator.admissionWebhooks.timeoutSeconds }} + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + {{- if or .Values.prometheusOperator.denyNamespaces .Values.prometheusOperator.namespaces .Values.prometheusOperator.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- with (omit .Values.prometheusOperator.admissionWebhooks.namespaceSelector "matchExpressions") }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- if or .Values.prometheusOperator.denyNamespaces .Values.prometheusOperator.namespaces .Values.prometheusOperator.admissionWebhooks.namespaceSelector.matchExpressions }} + matchExpressions: + {{- with (.Values.prometheusOperator.admissionWebhooks.namespaceSelector.matchExpressions) }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- if .Values.prometheusOperator.denyNamespaces }} + - key: kubernetes.io/metadata.name + operator: NotIn + values: + {{- range $namespace := mustUniq .Values.prometheusOperator.denyNamespaces }} + - {{ $namespace }} + {{- end }} + {{- else if and .Values.prometheusOperator.namespaces .Values.prometheusOperator.namespaces.additional }} + - key: kubernetes.io/metadata.name + operator: In + values: + {{- if and .Values.prometheusOperator.namespaces.releaseNamespace (default .Values.prometheusOperator.namespaces.releaseNamespace true) }} + {{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} + - {{ $namespace }} + {{- end }} + {{- range $namespace := mustUniq .Values.prometheusOperator.namespaces.additional }} + - {{ $namespace }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.prometheusOperator.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml new file mode 100644 index 0000000000..f21a9a72b1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/admission-webhooks/validatingWebhookConfiguration.yaml @@ -0,0 +1,81 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.admissionWebhooks.enabled }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission +{{- if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }} + annotations: + certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-admission" (include "kube-prometheus-stack.namespace" .) (include "kube-prometheus-stack.fullname" .) | quote }} + cert-manager.io/inject-ca-from: {{ printf "%s/%s-admission" (include "kube-prometheus-stack.namespace" .) (include "kube-prometheus-stack.fullname" .) | quote }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-admission + {{- include "kube-prometheus-stack.prometheus-operator-webhook.labels" $ | nindent 4 }} +webhooks: + - name: prometheusrulemutate.monitoring.coreos.com + {{- if eq .Values.prometheusOperator.admissionWebhooks.failurePolicy "IgnoreOnInstallOnly" }} + failurePolicy: {{ .Release.IsInstall | ternary "Ignore" "Fail" }} + {{- else if .Values.prometheusOperator.admissionWebhooks.failurePolicy }} + failurePolicy: {{ .Values.prometheusOperator.admissionWebhooks.failurePolicy }} + {{- else if .Values.prometheusOperator.admissionWebhooks.patch.enabled }} + failurePolicy: Ignore + {{- else }} + failurePolicy: Fail + {{- end }} + rules: + - apiGroups: + - monitoring.coreos.com + apiVersions: + - "*" + resources: + - prometheusrules + operations: + - CREATE + - UPDATE + clientConfig: + service: + namespace: {{ template "kube-prometheus-stack.namespace" . }} + name: {{ template "kube-prometheus-stack.operator.fullname" $ }}{{ if .Values.prometheusOperator.admissionWebhooks.deployment.enabled }}-webhook{{ end }} + path: /admission-prometheusrules/validate + {{- if and .Values.prometheusOperator.admissionWebhooks.caBundle (not .Values.prometheusOperator.admissionWebhooks.patch.enabled) (not .Values.prometheusOperator.admissionWebhooks.certManager.enabled) }} + caBundle: {{ .Values.prometheusOperator.admissionWebhooks.caBundle }} + {{- end }} + timeoutSeconds: {{ .Values.prometheusOperator.admissionWebhooks.timeoutSeconds }} + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + {{- if or .Values.prometheusOperator.denyNamespaces .Values.prometheusOperator.namespaces .Values.prometheusOperator.admissionWebhooks.namespaceSelector }} + namespaceSelector: + {{- with (omit .Values.prometheusOperator.admissionWebhooks.namespaceSelector "matchExpressions") }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- if or .Values.prometheusOperator.denyNamespaces .Values.prometheusOperator.namespaces .Values.prometheusOperator.admissionWebhooks.namespaceSelector.matchExpressions }} + matchExpressions: + {{- with (.Values.prometheusOperator.admissionWebhooks.namespaceSelector.matchExpressions) }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.prometheusOperator.denyNamespaces }} + - key: kubernetes.io/metadata.name + operator: NotIn + values: + {{- range $namespace := mustUniq .Values.prometheusOperator.denyNamespaces }} + - {{ $namespace }} + {{- end }} + {{- else if and .Values.prometheusOperator.namespaces .Values.prometheusOperator.namespaces.additional }} + - key: kubernetes.io/metadata.name + operator: In + values: + {{- if and .Values.prometheusOperator.namespaces.releaseNamespace (default .Values.prometheusOperator.namespaces.releaseNamespace true) }} + {{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} + - {{ $namespace }} + {{- end }} + {{- range $namespace := mustUniq .Values.prometheusOperator.namespaces.additional }} + - {{ $namespace }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.prometheusOperator.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/aggregate-clusterroles.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/aggregate-clusterroles.yaml new file mode 100644 index 0000000000..0c52000d6d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/aggregate-clusterroles.yaml @@ -0,0 +1,29 @@ +{{/* This file is based on https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/rbac-crd.md */}} +{{- if and .Values.global.rbac.create .Values.global.rbac.createAggregateClusterRoles }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-crd-view + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-view: "true" + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +rules: +- apiGroups: ["monitoring.coreos.com"] + resources: ["alertmanagers", "alertmanagerconfigs", "podmonitors", "probes", "prometheuses", "prometheusagents", "prometheusrules", "scrapeconfigs", "servicemonitors"] + verbs: ["get", "list", "watch"] +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-crd-edit + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +rules: +- apiGroups: ["monitoring.coreos.com"] + resources: ["alertmanagers", "alertmanagerconfigs", "podmonitors", "probes", "prometheuses", "prometheusagents", "prometheusrules", "scrapeconfigs", "servicemonitors"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/certmanager.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/certmanager.yaml new file mode 100644 index 0000000000..cb27e49f48 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/certmanager.yaml @@ -0,0 +1,55 @@ +{{- if .Values.prometheusOperator.admissionWebhooks.certManager.enabled -}} +{{- if not .Values.prometheusOperator.admissionWebhooks.certManager.issuerRef -}} +# Create a selfsigned Issuer, in order to create a root CA certificate for +# signing webhook serving certificates +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-self-signed-issuer + namespace: {{ template "kube-prometheus-stack.namespace" . }} +spec: + selfSigned: {} +--- +# Generate a CA Certificate used to sign certificates for the webhook +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-root-cert + namespace: {{ template "kube-prometheus-stack.namespace" . }} +spec: + secretName: {{ template "kube-prometheus-stack.fullname" . }}-root-cert + duration: {{ .Values.prometheusOperator.admissionWebhooks.certManager.rootCert.duration | default "43800h0m0s" | quote }} + issuerRef: + name: {{ template "kube-prometheus-stack.fullname" . }}-self-signed-issuer + commonName: "ca.webhook.kube-prometheus-stack" + isCA: true +--- +# Create an Issuer that uses the above generated CA certificate to issue certs +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-root-issuer + namespace: {{ template "kube-prometheus-stack.namespace" . }} +spec: + ca: + secretName: {{ template "kube-prometheus-stack.fullname" . }}-root-cert +{{- end }} +--- +# generate a server certificate for the apiservices to use +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + namespace: {{ template "kube-prometheus-stack.namespace" . }} +spec: + secretName: {{ template "kube-prometheus-stack.fullname" . }}-admission + duration: {{ .Values.prometheusOperator.admissionWebhooks.certManager.admissionCert.duration | default "8760h0m0s" | quote }} + issuerRef: + {{- if .Values.prometheusOperator.admissionWebhooks.certManager.issuerRef }} + {{- toYaml .Values.prometheusOperator.admissionWebhooks.certManager.issuerRef | nindent 4 }} + {{- else }} + name: {{ template "kube-prometheus-stack.fullname" . }}-root-issuer + {{- end }} + dnsNames: + {{- include "kube-prometheus-stack.operator.admission-webhook.dnsNames" . | splitList "\n" | toYaml | nindent 4 }} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000000..07e2e99967 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/ciliumnetworkpolicy.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "cilium") }} +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} + app: {{ template "kube-prometheus-stack.name" . }}-operator + {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} + {{- else }} + {{- include "kube-prometheus-stack.prometheus-operator.labels" $ | nindent 6 }} + {{- end }} + egress: + {{- if and .Values.prometheusOperator.networkPolicy.cilium .Values.prometheusOperator.networkPolicy.cilium.egress }} + {{ toYaml .Values.prometheusOperator.networkPolicy.cilium.egress | nindent 6 }} + {{- else }} + - toEntities: + - kube-apiserver + {{- end }} + ingress: + - toPorts: + - ports: + {{- if .Values.prometheusOperator.tls.enabled }} + - port: {{ .Values.prometheusOperator.tls.internalPort | quote }} + {{- else }} + - port: "8080" + {{- end }} + protocol: "TCP" + {{- if not .Values.prometheusOperator.tls.enabled }} + rules: + http: + - method: "GET" + path: "/metrics" + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/clusterrole.yaml new file mode 100644 index 0000000000..fd11b69eed --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/clusterrole.yaml @@ -0,0 +1,109 @@ +{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +rules: +- apiGroups: + - monitoring.coreos.com + resources: + - alertmanagers + - alertmanagers/finalizers + - alertmanagers/status + - alertmanagerconfigs + - prometheuses + - prometheuses/finalizers + - prometheuses/status + - prometheusagents + - prometheusagents/finalizers + - prometheusagents/status + - thanosrulers + - thanosrulers/finalizers + - thanosrulers/status + - scrapeconfigs + - servicemonitors + - podmonitors + - probes + - prometheusrules + verbs: + - '*' +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - '*' +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - '*' +- apiGroups: + - "" + resources: + - pods + verbs: + - list + - delete +- apiGroups: + - "" + resources: + - services + - services/finalizers + - endpoints + verbs: + - get + - create + - update + - delete +- apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - patch + - create +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get +{{- if .Capabilities.APIVersions.Has "discovery.k8s.io/v1/EndpointSlice" }} +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/clusterrolebinding.yaml new file mode 100644 index 0000000000..ad9e3ef6c5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kube-prometheus-stack.operator.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/deployment.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/deployment.yaml new file mode 100644 index 0000000000..b71e7d25d6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/deployment.yaml @@ -0,0 +1,207 @@ +{{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} +{{- $defaultKubeletSvcName := printf "%s-kubelet" (include "kube-prometheus-stack.fullname" .) }} +{{- if .Values.prometheusOperator.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +{{- if .Values.prometheusOperator.labels }} +{{ toYaml .Values.prometheusOperator.labels | indent 4 }} +{{- end }} +{{- if .Values.prometheusOperator.annotations }} + annotations: +{{ toYaml .Values.prometheusOperator.annotations | indent 4 }} +{{- end }} +spec: + replicas: 1 + revisionHistoryLimit: {{ .Values.prometheusOperator.revisionHistoryLimit }} + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-operator + release: {{ $.Release.Name | quote }} + {{- with .Values.prometheusOperator.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 8 }} +{{- if .Values.prometheusOperator.podLabels }} +{{ toYaml .Values.prometheusOperator.podLabels | indent 8 }} +{{- end }} +{{- if .Values.prometheusOperator.podAnnotations }} + annotations: +{{ toYaml .Values.prometheusOperator.podAnnotations | indent 8 }} +{{- end }} + spec: + {{- if .Values.prometheusOperator.priorityClassName }} + priorityClassName: {{ .Values.prometheusOperator.priorityClassName }} + {{- end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "kube-prometheus-stack.imagePullSecrets" . | indent 8 }} + {{- end }} + containers: + - name: {{ template "kube-prometheus-stack.name" . }} + {{- $base_registry := (include "monitoring_registry" .) }} + {{- $configReloaderRegistry := $base_registry | default .Values.prometheusOperator.prometheusConfigReloader.image.registry -}} + {{- $operatorRegistry := $base_registry | default .Values.prometheusOperator.image.registry -}} + {{- $thanosRegistry := $base_registry | default .Values.prometheusOperator.thanosImage.registry -}} + {{- if .Values.prometheusOperator.image.sha }} + image: "{{ $operatorRegistry }}/{{ .Values.prometheusOperator.image.repository }}:{{ .Values.prometheusOperator.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.prometheusOperator.image.sha }}" + {{- else }} + image: "{{ $operatorRegistry }}/{{ .Values.prometheusOperator.image.repository }}:{{ .Values.prometheusOperator.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: "{{ .Values.prometheusOperator.image.pullPolicy }}" + args: + {{- if .Values.prometheusOperator.kubeletService.enabled }} + - --kubelet-service={{ .Values.prometheusOperator.kubeletService.namespace }}/{{ default $defaultKubeletSvcName .Values.prometheusOperator.kubeletService.name }} + {{- if .Values.prometheusOperator.kubeletService.selector }} + - --kubelet-selector={{ .Values.prometheusOperator.kubeletService.selector }} + {{- end }} + {{- end }} + {{- if .Values.prometheusOperator.logFormat }} + - --log-format={{ .Values.prometheusOperator.logFormat }} + {{- end }} + {{- if .Values.prometheusOperator.logLevel }} + - --log-level={{ .Values.prometheusOperator.logLevel }} + {{- end }} + {{- if .Values.prometheusOperator.denyNamespaces }} + - --deny-namespaces={{ tpl (.Values.prometheusOperator.denyNamespaces | join ",") $ }} + {{- end }} + {{- with $.Values.prometheusOperator.namespaces }} + {{- $namespaces := list }} + {{- if .releaseNamespace }} + {{- $namespaces = append $namespaces $namespace }} + {{- end }} + {{- if .additional }} + {{- range $ns := .additional }} + {{- $namespaces = append $namespaces (tpl $ns $) }} + {{- end }} + {{- end }} + - --namespaces={{ $namespaces | mustUniq | join "," }} + {{- end }} + - --localhost=127.0.0.1 + {{- if .Values.prometheusOperator.prometheusDefaultBaseImage }} + - --prometheus-default-base-image={{ $base_registry | default .Values.prometheusOperator.prometheusDefaultBaseImageRegistry }}/{{ .Values.prometheusOperator.prometheusDefaultBaseImage }} + {{- end }} + {{- if .Values.prometheusOperator.alertmanagerDefaultBaseImage }} + - --alertmanager-default-base-image={{ $base_registry | default .Values.prometheusOperator.alertmanagerDefaultBaseImageRegistry }}/{{ .Values.prometheusOperator.alertmanagerDefaultBaseImage }} + {{- end }} + {{- if .Values.prometheusOperator.prometheusConfigReloader.image.sha }} + - --prometheus-config-reloader={{ $configReloaderRegistry }}/{{ .Values.prometheusOperator.prometheusConfigReloader.image.repository }}:{{ .Values.prometheusOperator.prometheusConfigReloader.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.prometheusOperator.prometheusConfigReloader.image.sha }} + {{- else }} + - --prometheus-config-reloader={{ $configReloaderRegistry }}/{{ .Values.prometheusOperator.prometheusConfigReloader.image.repository }}:{{ .Values.prometheusOperator.prometheusConfigReloader.image.tag | default .Chart.AppVersion }} + {{- end }} + - --config-reloader-cpu-request={{ (((.Values.prometheusOperator.prometheusConfigReloader.resources).requests).cpu) | default 0 }} + - --config-reloader-cpu-limit={{ (((.Values.prometheusOperator.prometheusConfigReloader.resources).limits).cpu) | default 0 }} + - --config-reloader-memory-request={{ (((.Values.prometheusOperator.prometheusConfigReloader.resources).requests).memory) | default 0 }} + - --config-reloader-memory-limit={{ (((.Values.prometheusOperator.prometheusConfigReloader.resources).limits).memory) | default 0 }} + {{- if .Values.prometheusOperator.prometheusConfigReloader.enableProbe }} + - --enable-config-reloader-probes=true + {{- end }} + {{- if .Values.prometheusOperator.alertmanagerInstanceNamespaces }} + - --alertmanager-instance-namespaces={{ .Values.prometheusOperator.alertmanagerInstanceNamespaces | join "," }} + {{- end }} + {{- if .Values.prometheusOperator.alertmanagerInstanceSelector }} + - --alertmanager-instance-selector={{ .Values.prometheusOperator.alertmanagerInstanceSelector }} + {{- end }} + {{- if .Values.prometheusOperator.alertmanagerConfigNamespaces }} + - --alertmanager-config-namespaces={{ .Values.prometheusOperator.alertmanagerConfigNamespaces | join "," }} + {{- end }} + {{- if .Values.prometheusOperator.prometheusInstanceNamespaces }} + - --prometheus-instance-namespaces={{ .Values.prometheusOperator.prometheusInstanceNamespaces | join "," }} + {{- end }} + {{- if .Values.prometheusOperator.prometheusInstanceSelector }} + - --prometheus-instance-selector={{ .Values.prometheusOperator.prometheusInstanceSelector }} + {{- end }} + {{- if .Values.prometheusOperator.thanosImage.sha }} + - --thanos-default-base-image={{ $thanosRegistry }}/{{ .Values.prometheusOperator.thanosImage.repository }}:{{ .Values.prometheusOperator.thanosImage.tag }}@sha256:{{ .Values.prometheusOperator.thanosImage.sha }} + {{- else }} + - --thanos-default-base-image={{ $thanosRegistry }}/{{ .Values.prometheusOperator.thanosImage.repository }}:{{ .Values.prometheusOperator.thanosImage.tag }} + {{- end }} + {{- if .Values.prometheusOperator.thanosRulerInstanceNamespaces }} + - --thanos-ruler-instance-namespaces={{ .Values.prometheusOperator.thanosRulerInstanceNamespaces | join "," }} + {{- end }} + {{- if .Values.prometheusOperator.thanosRulerInstanceSelector }} + - --thanos-ruler-instance-selector={{ .Values.prometheusOperator.thanosRulerInstanceSelector }} + {{- end }} + {{- if .Values.prometheusOperator.secretFieldSelector }} + - --secret-field-selector={{ tpl (.Values.prometheusOperator.secretFieldSelector) $ }} + {{- end }} + {{- if .Values.prometheusOperator.clusterDomain }} + - --cluster-domain={{ .Values.prometheusOperator.clusterDomain }} + {{- end }} + {{- if .Values.prometheusOperator.tls.enabled }} + - --web.enable-tls=true + - --web.cert-file=/cert/{{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}tls.crt{{ else }}cert{{ end }} + - --web.key-file=/cert/{{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}tls.key{{ else }}key{{ end }} + - --web.listen-address=:{{ .Values.prometheusOperator.tls.internalPort }} + - --web.tls-min-version={{ .Values.prometheusOperator.tls.tlsMinVersion }} + ports: + - containerPort: {{ .Values.prometheusOperator.tls.internalPort }} + name: https + {{- else }} + ports: + - containerPort: 8080 + name: http + {{- end }} + env: + {{- range $key, $value := .Values.prometheusOperator.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + resources: +{{ toYaml .Values.prometheusOperator.resources | indent 12 }} + securityContext: +{{ toYaml .Values.prometheusOperator.containerSecurityContext | indent 12 }} + volumeMounts: + {{- if .Values.prometheusOperator.tls.enabled }} + - name: tls-secret + mountPath: /cert + readOnly: true + {{- end }} + {{- with .Values.prometheusOperator.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + {{- if .Values.prometheusOperator.tls.enabled }} + - name: tls-secret + secret: + defaultMode: 420 + secretName: {{ template "kube-prometheus-stack.fullname" . }}-admission + {{- end }} + {{- with .Values.prometheusOperator.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.prometheusOperator.dnsConfig }} + dnsConfig: +{{ toYaml . | indent 8 }} + {{- end }} +{{- if .Values.prometheusOperator.securityContext }} + securityContext: +{{ toYaml .Values.prometheusOperator.securityContext | indent 8 }} +{{- end }} + serviceAccountName: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.prometheusOperator.automountServiceAccountToken }} +{{- if .Values.prometheusOperator.hostNetwork }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet +{{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} +{{- with .Values.prometheusOperator.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + {{- with .Values.prometheusOperator.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} +{{- with .Values.prometheusOperator.tolerations }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/networkpolicy.yaml new file mode 100644 index 0000000000..cfd5b0b8c7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/networkpolicy.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.prometheusOperator.networkPolicy.enabled (eq .Values.prometheusOperator.networkPolicy.flavor "kubernetes") }} +apiVersion: {{ template "kube-prometheus-stack.prometheus.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +spec: + egress: + - {} + ingress: + - ports: + {{- if .Values.prometheusOperator.tls.enabled }} + - port: {{ .Values.prometheusOperator.tls.internalPort }} + {{- else }} + - port: 8080 + {{- end }} + policyTypes: + - Egress + - Ingress + podSelector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-operator + release: {{ $.Release.Name | quote }} + {{- if .Values.prometheusOperator.networkPolicy.matchLabels }} + {{ toYaml .Values.prometheusOperator.networkPolicy.matchLabels | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp-clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp-clusterrole.yaml new file mode 100644 index 0000000000..9766238968 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp-clusterrole.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }}-psp + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +rules: +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} +- apiGroups: ['policy'] +{{- else }} +- apiGroups: ['extensions'] +{{- end }} + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-prometheus-stack.operator.fullname" . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..01f5f3d9dd --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp-clusterrolebinding.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }}-psp + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kube-prometheus-stack.operator.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp.yaml new file mode 100644 index 0000000000..0943b5f563 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/psp.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.prometheusOperator.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +{{- if .Values.global.rbac.pspAnnotations }} + annotations: +{{ toYaml .Values.global.rbac.pspAnnotations | indent 4 }} +{{- end }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: {{ .Values.prometheusOperator.hostNetwork }} + hostIPC: false + hostPID: false + runAsUser: + # Permits the container to run with root privileges as well. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/service.yaml new file mode 100644 index 0000000000..72e0788abf --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/service.yaml @@ -0,0 +1,61 @@ +{{- if .Values.prometheusOperator.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +{{- if .Values.prometheusOperator.service.labels }} +{{ toYaml .Values.prometheusOperator.service.labels | indent 4 }} +{{- end }} +{{- if .Values.prometheusOperator.service.annotations }} + annotations: +{{ toYaml .Values.prometheusOperator.service.annotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.prometheusOperator.service.clusterIP }} + clusterIP: {{ .Values.prometheusOperator.service.clusterIP }} +{{- end }} +{{- if .Values.prometheusOperator.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.prometheusOperator.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.prometheusOperator.service.ipDualStack.ipFamilyPolicy }} +{{- end }} +{{- if .Values.prometheusOperator.service.externalIPs }} + externalIPs: +{{ toYaml .Values.prometheusOperator.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.prometheusOperator.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.prometheusOperator.service.loadBalancerIP }} +{{- end }} +{{- if .Values.prometheusOperator.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.prometheusOperator.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if ne .Values.prometheusOperator.service.type "ClusterIP" }} + externalTrafficPolicy: {{ .Values.prometheusOperator.service.externalTrafficPolicy }} +{{- end }} + ports: + {{- if not .Values.prometheusOperator.tls.enabled }} + - name: http + {{- if eq .Values.prometheusOperator.service.type "NodePort" }} + nodePort: {{ .Values.prometheusOperator.service.nodePort }} + {{- end }} + port: 8080 + targetPort: http + {{- end }} + {{- if .Values.prometheusOperator.tls.enabled }} + - name: https + {{- if eq .Values.prometheusOperator.service.type "NodePort"}} + nodePort: {{ .Values.prometheusOperator.service.nodePortTls }} + {{- end }} + port: 443 + targetPort: https + {{- end }} + selector: + app: {{ template "kube-prometheus-stack.name" . }}-operator + release: {{ $.Release.Name | quote }} + type: "{{ .Values.prometheusOperator.service.type }}" +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/serviceaccount.yaml new file mode 100644 index 0000000000..4f84974f9b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kube-prometheus-stack.operator.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +automountServiceAccountToken: {{ .Values.prometheusOperator.serviceAccount.automountServiceAccountToken }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/servicemonitor.yaml new file mode 100644 index 0000000000..cbe79e1253 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/servicemonitor.yaml @@ -0,0 +1,57 @@ +{{- if and .Values.prometheusOperator.enabled .Values.prometheusOperator.serviceMonitor.selfMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +{{- with .Values.prometheusOperator.serviceMonitor.additionalLabels }} +{{ toYaml . | indent 4 }} +{{- end }} +spec: + {{- include "servicemonitor.scrapeLimits" .Values.prometheusOperator.serviceMonitor | nindent 2 }} + endpoints: + {{- if .Values.prometheusOperator.tls.enabled }} + - port: https + scheme: https + tlsConfig: + serverName: {{ template "kube-prometheus-stack.operator.fullname" . }} + ca: + secret: + name: {{ template "kube-prometheus-stack.fullname" . }}-admission + key: {{ if .Values.prometheusOperator.admissionWebhooks.certManager.enabled }}ca.crt{{ else }}ca{{ end }} + optional: false + {{- else }} + - port: http + {{- end }} + honorLabels: true + {{- if .Values.prometheusOperator.serviceMonitor.interval }} + interval: {{ .Values.prometheusOperator.serviceMonitor.interval }} + {{- end }} + metricRelabelings: + {{- if .Values.prometheusOperator.serviceMonitor.metricRelabelings }} + {{ tpl (toYaml .Values.prometheusOperator.serviceMonitor.metricRelabelings | indent 6) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.prometheusOperator.serviceMonitor.relabelings }} + relabelings: +{{ toYaml .Values.prometheusOperator.serviceMonitor.relabelings | indent 6 }} +{{- end }} + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-operator + release: {{ $.Release.Name | quote }} + namespaceSelector: + matchNames: + - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/verticalpodautoscaler.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/verticalpodautoscaler.yaml new file mode 100644 index 0000000000..f225d16dde --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus-operator/verticalpodautoscaler.yaml @@ -0,0 +1,40 @@ +{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (.Values.prometheusOperator.verticalPodAutoscaler.enabled) }} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + {{- include "kube-prometheus-stack.prometheus-operator.labels" . | nindent 4 }} +spec: + {{- with .Values.prometheusOperator.verticalPodAutoscaler.recommenders }} + recommenders: + {{- toYaml . | nindent 4 }} + {{- end }} + resourcePolicy: + containerPolicies: + - containerName: {{ template "kube-prometheus-stack.name" . }} + {{- with .Values.prometheusOperator.verticalPodAutoscaler.controlledResources }} + controlledResources: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.prometheusOperator.verticalPodAutoscaler.controlledValues }} + controlledValues: {{ .Values.prometheusOperator.verticalPodAutoscaler.controlledValues }} + {{- end }} + {{- if .Values.prometheusOperator.verticalPodAutoscaler.maxAllowed }} + maxAllowed: + {{- toYaml .Values.prometheusOperator.verticalPodAutoscaler.maxAllowed | nindent 8 }} + {{- end }} + {{- if .Values.prometheusOperator.verticalPodAutoscaler.minAllowed }} + minAllowed: + {{- toYaml .Values.prometheusOperator.verticalPodAutoscaler.minAllowed | nindent 8 }} + {{- end }} + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "kube-prometheus-stack.operator.fullname" . }} + {{- with .Values.prometheusOperator.verticalPodAutoscaler.updatePolicy }} + updatePolicy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/_rules.tpl b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/_rules.tpl new file mode 100644 index 0000000000..4a8213d089 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/_rules.tpl @@ -0,0 +1,44 @@ +{{- /* +Generated file. Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- define "rules.names" }} +rules: + - "alertmanager.rules" + - "config-reloaders" + - "etcd" + - "general.rules" + - "k8s.rules.container-cpu-usage-seconds-total" + - "k8s.rules.container-memory-cache" + - "k8s.rules.container-memory-rss" + - "k8s.rules.container-memory-swap" + - "k8s.rules.container-memory-working-set-bytes" + - "k8s.rules.container-resource" + - "k8s.rules.pod-owner" + - "kube-apiserver-availability.rules" + - "kube-apiserver-burnrate.rules" + - "kube-apiserver-histogram.rules" + - "kube-apiserver-slos" + - "kube-prometheus-general.rules" + - "kube-prometheus-node-recording.rules" + - "kube-scheduler.rules" + - "kube-state-metrics" + - "kubelet.rules" + - "kubernetes-apps" + - "kubernetes-resources" + - "kubernetes-storage" + - "kubernetes-system" + - "kubernetes-system-kube-proxy" + - "kubernetes-system-apiserver" + - "kubernetes-system-kubelet" + - "kubernetes-system-controller-manager" + - "kubernetes-system-scheduler" + - "node-exporter.rules" + - "node-exporter" + - "node.rules" + - "node-network" + - "prometheus-operator" + - "prometheus" + - "windows.node.rules" + - "windows.pod.rules" +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalAlertRelabelConfigs.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalAlertRelabelConfigs.yaml new file mode 100644 index 0000000000..bff930981a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalAlertRelabelConfigs.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigs }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-am-relabel-confg + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- if .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations }} + annotations: +{{ toYaml .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus-am-relabel-confg +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: + additional-alert-relabel-configs.yaml: {{ toYaml .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigs | b64enc | quote }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalAlertmanagerConfigs.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalAlertmanagerConfigs.yaml new file mode 100644 index 0000000000..2fe8fdb816 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalAlertmanagerConfigs.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.prometheusSpec.additionalAlertManagerConfigs }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-am-confg + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- if .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations }} + annotations: +{{ toYaml .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus-am-confg +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: + additional-alertmanager-configs.yaml: {{ tpl (toYaml .Values.prometheus.prometheusSpec.additionalAlertManagerConfigs) . | b64enc | quote }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalPrometheusRules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalPrometheusRules.yaml new file mode 100644 index 0000000000..cb4aabaa7b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalPrometheusRules.yaml @@ -0,0 +1,43 @@ +{{- if or .Values.additionalPrometheusRules .Values.additionalPrometheusRulesMap}} +apiVersion: v1 +kind: List +metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-additional-prometheus-rules + namespace: {{ template "kube-prometheus-stack.namespace" . }} +items: +{{- if .Values.additionalPrometheusRulesMap }} +{{- range $prometheusRuleName, $prometheusRule := .Values.additionalPrometheusRulesMap }} + - apiVersion: monitoring.coreos.com/v1 + kind: PrometheusRule + metadata: + name: {{ template "kube-prometheus-stack.name" $ }}-{{ $prometheusRuleName }} + namespace: {{ template "kube-prometheus-stack.namespace" $ }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }} +{{ include "kube-prometheus-stack.labels" $ | indent 8 }} + {{- if $prometheusRule.additionalLabels }} +{{ toYaml $prometheusRule.additionalLabels | indent 8 }} + {{- end }} + spec: + groups: +{{ toYaml $prometheusRule.groups| indent 8 }} +{{- end }} +{{- else }} +{{- range .Values.additionalPrometheusRules }} + - apiVersion: monitoring.coreos.com/v1 + kind: PrometheusRule + metadata: + name: {{ template "kube-prometheus-stack.name" $ }}-{{ .name }} + namespace: {{ template "kube-prometheus-stack.namespace" $ }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }} +{{ include "kube-prometheus-stack.labels" $ | indent 8 }} + {{- if .additionalLabels }} +{{ toYaml .additionalLabels | indent 8 }} + {{- end }} + spec: + groups: +{{ toYaml .groups| indent 8 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalScrapeConfigs.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalScrapeConfigs.yaml new file mode 100644 index 0000000000..ebdf766fde --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/additionalScrapeConfigs.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.prometheusSpec.additionalScrapeConfigs }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-scrape-confg + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- if .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations }} + annotations: +{{ toYaml .Values.prometheus.prometheusSpec.additionalPrometheusSecretsAnnotations | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus-scrape-confg +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: +{{- if eq ( typeOf .Values.prometheus.prometheusSpec.additionalScrapeConfigs ) "string" }} + additional-scrape-configs.yaml: {{ tpl .Values.prometheus.prometheusSpec.additionalScrapeConfigs $ | b64enc | quote }} +{{- else }} + additional-scrape-configs.yaml: {{ tpl (toYaml .Values.prometheus.prometheusSpec.additionalScrapeConfigs) $ | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ciliumnetworkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000000..74d61d7c13 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ciliumnetworkpolicy.yaml @@ -0,0 +1,27 @@ +{{- if and .Values.prometheus.networkPolicy.enabled (eq .Values.prometheus.networkPolicy.flavor "cilium") }} +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus + {{- include "kube-prometheus-stack.labels" . | nindent 4 }} +spec: + endpointSelector: + {{- if .Values.prometheus.networkPolicy.cilium.endpointSelector }} + {{- toYaml .Values.prometheus.networkPolicy.cilium.endpointSelector | nindent 4 }} + {{- else }} + matchExpressions: + - {key: app.kubernetes.io/name, operator: In, values: [prometheus]} + - {key: prometheus, operator: In, values: [{{ template "kube-prometheus-stack.prometheus.crname" . }}]} + {{- end }} + {{- if and .Values.prometheus.networkPolicy.cilium .Values.prometheus.networkPolicy.cilium.egress }} + egress: + {{ toYaml .Values.prometheus.networkPolicy.cilium.egress | nindent 4 }} + {{- end }} + {{- if and .Values.prometheus.networkPolicy.cilium .Values.prometheus.networkPolicy.cilium.ingress }} + ingress: + {{ toYaml .Values.prometheus.networkPolicy.cilium.ingress | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/clusterrole.yaml new file mode 100644 index 0000000000..eabdb24b95 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/clusterrole.yaml @@ -0,0 +1,43 @@ +{{- if and .Values.prometheus.enabled .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +rules: +# This permission are not in the kube-prometheus repo +# they're grabbed from https://github.com/prometheus/prometheus/blob/master/documentation/examples/rbac-setup.yml +- apiGroups: [""] + resources: + - nodes + - 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"] +{{/* fix(#3338): add required rules to use node-exporter with the RBAC proxy */}} +{{- if and .Values.nodeExporter.enabled (index .Values "prometheus-node-exporter").kubeRBACProxy.enabled }} +- apiGroups: [ "" ] + resources: + - services/{{ include "prometheus-node-exporter.fullname" (index .Subcharts "prometheus-node-exporter") }} + verbs: [ "get", "list", "watch" ] +{{- end }} +{{- if and .Values.kubeStateMetrics.enabled (index .Values "kube-state-metrics").kubeRBACProxy.enabled }} +- apiGroups: [ "" ] + resources: + - services/{{ include "kube-state-metrics.fullname" (index .Subcharts "kube-state-metrics") }} + verbs: [ "get", "list", "watch" ] +{{- end }} +{{- if .Values.prometheus.additionalRulesForClusterRole }} +{{ toYaml .Values.prometheus.additionalRulesForClusterRole | indent 0 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/clusterrolebinding.yaml new file mode 100644 index 0000000000..9fc4f65da4 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/clusterrolebinding.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.prometheus.enabled .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus +subjects: + - kind: ServiceAccount + name: {{ template "kube-prometheus-stack.prometheus.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- end }} + diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/csi-secret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/csi-secret.yaml new file mode 100644 index 0000000000..e05382f633 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/csi-secret.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.prometheus.prometheusSpec.thanos .Values.prometheus.prometheusSpec.thanos.secretProviderClass }} +--- +apiVersion: secrets-store.csi.x-k8s.io/v1alpha1 +kind: SecretProviderClass +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +spec: +{{ toYaml .Values.prometheus.prometheusSpec.thanos.secretProviderClass | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/extrasecret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/extrasecret.yaml new file mode 100644 index 0000000000..17f3478a46 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/extrasecret.yaml @@ -0,0 +1,20 @@ +{{- if .Values.prometheus.extraSecret.data -}} +{{- $secretName := printf "prometheus-%s-extra" (include "kube-prometheus-stack.fullname" . ) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default $secretName .Values.prometheus.extraSecret.name }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- if .Values.prometheus.extraSecret.annotations }} + annotations: +{{ toYaml .Values.prometheus.extraSecret.annotations | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus + app.kubernetes.io/component: prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: +{{- range $key, $val := .Values.prometheus.extraSecret.data }} + {{ $key }}: {{ $val | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingress.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingress.yaml new file mode 100644 index 0000000000..d2f6af5dd1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingress.yaml @@ -0,0 +1,77 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.ingress.enabled -}} + {{- $pathType := .Values.prometheus.ingress.pathType | default "ImplementationSpecific" -}} + {{- $serviceName := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "prometheus" -}} + {{- $servicePort := .Values.prometheus.ingress.servicePort | default .Values.prometheus.service.port -}} + {{- $routePrefix := list .Values.prometheus.prometheusSpec.routePrefix -}} + {{- $paths := .Values.prometheus.ingress.paths | default $routePrefix -}} + {{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} + {{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} +apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" . }} +kind: Ingress +metadata: +{{- if .Values.prometheus.ingress.annotations }} + annotations: + {{- tpl (toYaml .Values.prometheus.ingress.annotations) . | nindent 4 }} +{{- end }} + name: {{ $serviceName }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.prometheus.ingress.labels }} +{{ toYaml .Values.prometheus.ingress.labels | indent 4 }} +{{- end }} +spec: + {{- if $apiIsStable }} + {{- if .Values.prometheus.ingress.ingressClassName }} + ingressClassName: {{ .Values.prometheus.ingress.ingressClassName }} + {{- end }} + {{- end }} + rules: + {{- if .Values.prometheus.ingress.hosts }} + {{- range $host := .Values.prometheus.ingress.hosts }} + - host: {{ tpl $host $ }} + http: + paths: + {{- range $p := $paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- else }} + - http: + paths: + {{- range $p := $paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- if .Values.prometheus.ingress.tls }} + tls: +{{ tpl (toYaml .Values.prometheus.ingress.tls | indent 4) . }} + {{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingressThanosSidecar.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingressThanosSidecar.yaml new file mode 100644 index 0000000000..3f507cfa9f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingressThanosSidecar.yaml @@ -0,0 +1,77 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.thanosIngress.enabled }} +{{- $pathType := .Values.prometheus.thanosIngress.pathType | default "" }} +{{- $serviceName := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "thanos-discovery" }} +{{- $thanosPort := .Values.prometheus.thanosIngress.servicePort -}} +{{- $routePrefix := list .Values.prometheus.prometheusSpec.routePrefix }} +{{- $paths := .Values.prometheus.thanosIngress.paths | default $routePrefix -}} +{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} +apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" . }} +kind: Ingress +metadata: +{{- if .Values.prometheus.thanosIngress.annotations }} + annotations: + {{- tpl (toYaml .Values.prometheus.thanosIngress.annotations) . | nindent 4 }} +{{- end }} + name: {{ template "kube-prometheus-stack.fullname" . }}-thanos-gateway + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.prometheus.thanosIngress.labels }} +{{ toYaml .Values.prometheus.thanosIngress.labels | indent 4 }} +{{- end }} +spec: + {{- if $apiIsStable }} + {{- if .Values.prometheus.thanosIngress.ingressClassName }} + ingressClassName: {{ .Values.prometheus.thanosIngress.ingressClassName }} + {{- end }} + {{- end }} + rules: + {{- if .Values.prometheus.thanosIngress.hosts }} + {{- range $host := .Values.prometheus.thanosIngress.hosts }} + - host: {{ tpl $host $ }} + http: + paths: + {{- range $p := $paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $thanosPort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $thanosPort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- else }} + - http: + paths: + {{- range $p := $paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $thanosPort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $thanosPort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- if .Values.prometheus.thanosIngress.tls }} + tls: +{{ tpl (toYaml .Values.prometheus.thanosIngress.tls | indent 4) . }} + {{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingressperreplica.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingressperreplica.yaml new file mode 100644 index 0000000000..1d76d135c8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/ingressperreplica.yaml @@ -0,0 +1,67 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.servicePerReplica.enabled .Values.prometheus.ingressPerReplica.enabled }} +{{- $pathType := .Values.prometheus.ingressPerReplica.pathType | default "" }} +{{- $count := .Values.prometheus.prometheusSpec.replicas | int -}} +{{- $servicePort := .Values.prometheus.servicePerReplica.port -}} +{{- $ingressValues := .Values.prometheus.ingressPerReplica -}} +{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} +apiVersion: v1 +kind: List +metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-ingressperreplica + namespace: {{ template "kube-prometheus-stack.namespace" $ }} +items: +{{ range $i, $e := until $count }} + - kind: Ingress + apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" $ }} + metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-{{ $i }} + namespace: {{ template "kube-prometheus-stack.namespace" $ }} + labels: + app: {{ include "kube-prometheus-stack.name" $ }}-prometheus + {{ include "kube-prometheus-stack.labels" $ | indent 8 }} + {{- if $ingressValues.labels }} +{{ toYaml $ingressValues.labels | indent 8 }} + {{- end }} + {{- if $ingressValues.annotations }} + annotations: + {{- tpl (toYaml $ingressValues.annotations) $ | nindent 8 }} + {{- end }} + spec: + {{- if $apiIsStable }} + {{- if $ingressValues.ingressClassName }} + ingressClassName: {{ $ingressValues.ingressClassName }} + {{- end }} + {{- end }} + rules: + - host: {{ $ingressValues.hostPrefix }}-{{ $i }}.{{ $ingressValues.hostDomain }} + http: + paths: + {{- range $p := $ingressValues.paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-{{ $i }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-{{ $i }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- if or $ingressValues.tlsSecretName $ingressValues.tlsSecretPerReplica.enabled }} + tls: + - hosts: + - {{ $ingressValues.hostPrefix }}-{{ $i }}.{{ $ingressValues.hostDomain }} + {{- if $ingressValues.tlsSecretPerReplica.enabled }} + secretName: {{ $ingressValues.tlsSecretPerReplica.prefix }}-{{ $i }} + {{- else }} + secretName: {{ $ingressValues.tlsSecretName }} + {{- end }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/networkpolicy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/networkpolicy.yaml new file mode 100644 index 0000000000..1296a79063 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/networkpolicy.yaml @@ -0,0 +1,34 @@ +{{- if and .Values.prometheus.networkPolicy.enabled (eq .Values.prometheus.networkPolicy.flavor "kubernetes") }} +apiVersion: {{ template "kube-prometheus-stack.prometheus.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus + {{- include "kube-prometheus-stack.labels" . | nindent 4 }} + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + namespace: {{ template "kube-prometheus-stack.namespace" . }} +spec: + {{- if .Values.prometheus.networkPolicy.egress }} + egress: + {{- toYaml .Values.prometheus.networkPolicy.egress | nindent 4 }} + {{- end }} + {{- if .Values.prometheus.networkPolicy.ingress }} + ingress: + {{- toYaml .Values.prometheus.networkPolicy.ingress | nindent 4 }} + {{- end }} + policyTypes: + - Egress + - Ingress + podSelector: + {{- if .Values.prometheus.networkPolicy.podSelector }} + {{- toYaml .Values.prometheus.networkPolicy.podSelector | nindent 4 }} + {{- else }} + matchLabels: + {{- if .Values.prometheus.agentMode }} + app.kubernetes.io/name: prometheus-agent + {{- else }} + app.kubernetes.io/name: prometheus + {{- end }} + operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/nginx-config.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/nginx-config.yaml new file mode 100644 index 0000000000..e4d91f9a9e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/nginx-config.yaml @@ -0,0 +1,68 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-nginx-proxy-config + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.prometheus.annotations }} + annotations: +{{ toYaml .Values.prometheus.annotations | indent 4 }} +{{- end }} +data: + nginx.conf: |- + worker_processes auto; + error_log /dev/stdout warn; + pid /var/cache/nginx/nginx.pid; + + events { + worker_connections 1024; + } + + http { + include /etc/nginx/mime.types; + log_format main '[$time_local - $status] $remote_addr - $remote_user $request ($http_referer)'; + + proxy_connect_timeout 10; + proxy_read_timeout 180; + proxy_send_timeout 5; + proxy_buffering off; + proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my_zone:100m inactive=1d max_size=10g; + + server { + listen 8081; + access_log off; + + gzip on; + gzip_min_length 1k; + gzip_comp_level 2; + gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript image/jpeg image/gif image/png; + gzip_vary on; + gzip_disable "MSIE [1-6]\."; + + proxy_set_header Host $host; + + location / { + proxy_cache my_zone; + proxy_cache_valid 200 302 1d; + proxy_cache_valid 301 30d; + proxy_cache_valid any 5m; + proxy_cache_bypass $http_cache_control; + add_header X-Proxy-Cache $upstream_cache_status; + add_header Cache-Control "public"; + + proxy_pass http://localhost:9090/; + + sub_filter_once off; + sub_filter 'var PATH_PREFIX = "";' 'var PATH_PREFIX = ".";'; + + if ($request_filename ~ .*\.(?:js|css|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$) { + expires 90d; + } + + rewrite ^/k8s/clusters/.*/proxy(.*) /$1 break; + + } + } + } diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/podDisruptionBudget.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/podDisruptionBudget.yaml new file mode 100644 index 0000000000..48f3f1f5a6 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/podDisruptionBudget.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.podDisruptionBudget.enabled }} +apiVersion: {{ include "kube-prometheus-stack.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + {{- if .Values.prometheus.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.prometheus.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.prometheus.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.prometheus.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- if .Values.prometheus.agentMode }} + app.kubernetes.io/name: prometheus-agent + {{- else }} + app.kubernetes.io/name: prometheus + {{- end }} + operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/podmonitors.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/podmonitors.yaml new file mode 100644 index 0000000000..4e748c23b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/podmonitors.yaml @@ -0,0 +1,38 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.additionalPodMonitors }} +apiVersion: v1 +kind: List +items: +{{- range .Values.prometheus.additionalPodMonitors }} + - apiVersion: monitoring.coreos.com/v1 + kind: PodMonitor + metadata: + name: {{ .name }} + namespace: {{ template "kube-prometheus-stack.namespace" $ }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-prometheus +{{ include "kube-prometheus-stack.labels" $ | indent 8 }} + {{- if .additionalLabels }} +{{ toYaml .additionalLabels | indent 8 }} + {{- end }} + spec: + {{- include "servicemonitor.scrapeLimits" . | nindent 6 }} + podMetricsEndpoints: +{{ toYaml .podMetricsEndpoints | indent 8 }} + {{- if .jobLabel }} + jobLabel: {{ .jobLabel }} + {{- end }} + {{- if .namespaceSelector }} + namespaceSelector: +{{ toYaml .namespaceSelector | indent 8 }} + {{- end }} + selector: +{{ toYaml .selector | indent 8 }} + {{- if .podTargetLabels }} + podTargetLabels: +{{ toYaml .podTargetLabels | indent 8 }} + {{- end }} + {{- if .sampleLimit }} + sampleLimit: {{ .sampleLimit }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/prometheus.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/prometheus.yaml new file mode 100644 index 0000000000..e668b40a9f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/prometheus.yaml @@ -0,0 +1,481 @@ +{{- if .Values.prometheus.enabled }} +{{- if .Values.prometheus.agentMode }} +apiVersion: monitoring.coreos.com/v1alpha1 +kind: PrometheusAgent +{{- else }} +apiVersion: monitoring.coreos.com/v1 +kind: Prometheus +{{- end }} +metadata: + name: {{ template "kube-prometheus-stack.prometheus.crname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.prometheus.annotations }} + annotations: +{{ toYaml .Values.prometheus.annotations | indent 4 }} +{{- end }} +spec: + automountServiceAccountToken: {{ .Values.prometheus.prometheusSpec.automountServiceAccountToken }} +{{- if and (not .Values.prometheus.agentMode) (or .Values.prometheus.prometheusSpec.alertingEndpoints .Values.alertmanager.enabled) }} + alerting: + alertmanagers: +{{- if .Values.prometheus.prometheusSpec.alertingEndpoints }} +{{ toYaml .Values.prometheus.prometheusSpec.alertingEndpoints | indent 6 }} +{{- else if .Values.alertmanager.enabled }} + - namespace: {{ template "kube-prometheus-stack.namespace" . }} + name: {{ template "kube-prometheus-stack.fullname" . }}-alertmanager + port: {{ .Values.alertmanager.alertmanagerSpec.portName }} + {{- if .Values.alertmanager.alertmanagerSpec.routePrefix }} + pathPrefix: "{{ .Values.alertmanager.alertmanagerSpec.routePrefix }}" + {{- end }} + {{- if .Values.alertmanager.alertmanagerSpec.scheme }} + scheme: {{ .Values.alertmanager.alertmanagerSpec.scheme }} + {{- end }} + {{- if .Values.alertmanager.alertmanagerSpec.tlsConfig }} + tlsConfig: +{{ toYaml .Values.alertmanager.alertmanagerSpec.tlsConfig | indent 10 }} + {{- end }} + apiVersion: {{ .Values.alertmanager.apiVersion }} +{{- end }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.apiserverConfig }} + apiserverConfig: +{{ toYaml .Values.prometheus.prometheusSpec.apiserverConfig | indent 4}} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.image }} + {{- $registry := include "monitoring_registry" . | default .Values.prometheus.prometheusSpec.image.registry -}} + {{- if and .Values.prometheus.prometheusSpec.image.tag .Values.prometheus.prometheusSpec.image.sha }} + image: "{{ $registry }}/{{ .Values.prometheus.prometheusSpec.image.repository }}:{{ .Values.prometheus.prometheusSpec.image.tag }}@sha256:{{ .Values.prometheus.prometheusSpec.image.sha }}" + {{- else if .Values.prometheus.prometheusSpec.image.sha }} + image: "{{ $registry }}/{{ .Values.prometheus.prometheusSpec.image.repository }}@sha256:{{ .Values.prometheus.prometheusSpec.image.sha }}" + {{- else if .Values.prometheus.prometheusSpec.image.tag }} + image: "{{ $registry }}/{{ .Values.prometheus.prometheusSpec.image.repository }}:{{ .Values.prometheus.prometheusSpec.image.tag }}" + {{- else }} + image: "{{ $registry }}/{{ .Values.prometheus.prometheusSpec.image.repository }}" + {{- end }} + version: {{ default .Values.prometheus.prometheusSpec.image.tag .Values.prometheus.prometheusSpec.version }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.additionalArgs }} + additionalArgs: +{{ toYaml .Values.prometheus.prometheusSpec.additionalArgs | indent 4}} +{{- end -}} +{{- if .Values.prometheus.prometheusSpec.externalLabels }} + externalLabels: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.externalLabels | indent 4) . }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.prometheusExternalLabelNameClear }} + prometheusExternalLabelName: "" +{{- else if .Values.prometheus.prometheusSpec.prometheusExternalLabelName }} + prometheusExternalLabelName: "{{ .Values.prometheus.prometheusSpec.prometheusExternalLabelName }}" +{{- end }} +{{- if .Values.prometheus.prometheusSpec.replicaExternalLabelNameClear }} + replicaExternalLabelName: "" +{{- else if .Values.prometheus.prometheusSpec.replicaExternalLabelName }} + replicaExternalLabelName: "{{ .Values.prometheus.prometheusSpec.replicaExternalLabelName }}" +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enableRemoteWriteReceiver }} + enableRemoteWriteReceiver: {{ .Values.prometheus.prometheusSpec.enableRemoteWriteReceiver }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.externalUrl }} + externalUrl: "{{ tpl .Values.prometheus.prometheusSpec.externalUrl . }}" +{{- else if and .Values.prometheus.ingress.enabled .Values.prometheus.ingress.hosts }} + externalUrl: "http://{{ tpl (index .Values.prometheus.ingress.hosts 0) . }}{{ .Values.prometheus.prometheusSpec.routePrefix }}" +{{- else if not (or (kindIs "invalid" .Values.global.cattle.url) (kindIs "invalid" .Values.global.cattle.clusterId)) }} + externalUrl: "{{ .Values.global.cattle.url }}/k8s/clusters/{{ .Values.global.cattle.clusterId }}/api/v1/namespaces/{{ template "kube-prometheus-stack.namespace" . }}/services/http:{{ template "kube-prometheus-stack.fullname" . }}-prometheus:{{ .Values.prometheus.service.port }}/proxy" +{{- else }} + externalUrl: http://{{ template "kube-prometheus-stack.fullname" . }}-prometheus.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.prometheus.service.port }} +{{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 4 }} +{{- if .Values.prometheus.prometheusSpec.nodeSelector }} +{{ toYaml .Values.prometheus.prometheusSpec.nodeSelector | indent 4 }} +{{- end }} + paused: {{ .Values.prometheus.prometheusSpec.paused }} + replicas: {{ .Values.prometheus.prometheusSpec.replicas }} + shards: {{ .Values.prometheus.prometheusSpec.shards }} + logLevel: {{ .Values.prometheus.prometheusSpec.logLevel }} + logFormat: {{ .Values.prometheus.prometheusSpec.logFormat }} + listenLocal: {{ .Values.prometheus.prometheusSpec.listenLocal }} +{{- if not .Values.prometheus.agentMode }} + enableAdminAPI: {{ .Values.prometheus.prometheusSpec.enableAdminAPI }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.web }} + web: +{{ toYaml .Values.prometheus.prometheusSpec.web | indent 4 }} +{{- end }} +{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.exemplars }} + exemplars: + {{- toYaml .Values.prometheus.prometheusSpec.exemplars | nindent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enableFeatures }} + enableFeatures: +{{- range $enableFeatures := .Values.prometheus.prometheusSpec.enableFeatures }} + - {{ tpl $enableFeatures $ }} +{{- end }} +{{- end }} +{{- with .Values.prometheus.prometheusSpec.scrapeClasses }} + scrapeClasses: + {{- tpl (toYaml . | nindent 4) $ }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.scrapeInterval }} + scrapeInterval: {{ .Values.prometheus.prometheusSpec.scrapeInterval }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.prometheusSpec.scrapeTimeout }} +{{- end }} +{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.evaluationInterval }} + evaluationInterval: {{ .Values.prometheus.prometheusSpec.evaluationInterval }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.resources }} + resources: +{{ toYaml .Values.prometheus.prometheusSpec.resources | indent 4 }} +{{- end }} +{{- if not .Values.prometheus.agentMode }} + retention: {{ .Values.prometheus.prometheusSpec.retention | quote }} +{{- if .Values.prometheus.prometheusSpec.retentionSize }} + retentionSize: {{ .Values.prometheus.prometheusSpec.retentionSize | quote }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.tsdb }} + tsdb: + {{- if .Values.prometheus.prometheusSpec.tsdb.outOfOrderTimeWindow }} + outOfOrderTimeWindow: {{ .Values.prometheus.prometheusSpec.tsdb.outOfOrderTimeWindow }} + {{- end }} +{{- end }} +{{- end }} +{{- if eq .Values.prometheus.prometheusSpec.walCompression false }} + walCompression: false +{{ else }} + walCompression: true +{{- end }} +{{- if .Values.prometheus.prometheusSpec.routePrefix }} + routePrefix: {{ .Values.prometheus.prometheusSpec.routePrefix | quote }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.secrets }} + secrets: +{{ toYaml .Values.prometheus.prometheusSpec.secrets | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.configMaps }} + configMaps: +{{ toYaml .Values.prometheus.prometheusSpec.configMaps | indent 4 }} +{{- end }} + serviceAccountName: {{ template "kube-prometheus-stack.prometheus.serviceAccountName" . }} +{{- if .Values.prometheus.prometheusSpec.serviceMonitorSelector }} + serviceMonitorSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.serviceMonitorSelector | indent 4) . }} +{{ else if .Values.prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues }} + serviceMonitorSelector: + matchLabels: + release: {{ $.Release.Name | quote }} +{{ else }} + serviceMonitorSelector: {} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.serviceMonitorNamespaceSelector }} + serviceMonitorNamespaceSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.serviceMonitorNamespaceSelector | indent 4) . }} +{{ else }} + serviceMonitorNamespaceSelector: {} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.podMonitorSelector }} + podMonitorSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.podMonitorSelector | indent 4) . }} +{{ else if .Values.prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues }} + podMonitorSelector: + matchLabels: + release: {{ $.Release.Name | quote }} +{{ else }} + podMonitorSelector: {} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.podMonitorNamespaceSelector }} + podMonitorNamespaceSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.podMonitorNamespaceSelector | indent 4) . }} +{{ else }} + podMonitorNamespaceSelector: {} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.probeSelector }} + probeSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.probeSelector | indent 4) . }} +{{ else if .Values.prometheus.prometheusSpec.probeSelectorNilUsesHelmValues }} + probeSelector: + matchLabels: + release: {{ $.Release.Name | quote }} +{{ else }} + probeSelector: {} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.probeNamespaceSelector }} + probeNamespaceSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.probeNamespaceSelector | indent 4) . }} +{{ else }} + probeNamespaceSelector: {} +{{- end }} +{{- if and (not .Values.prometheus.agentMode) (or .Values.prometheus.prometheusSpec.remoteRead .Values.prometheus.prometheusSpec.additionalRemoteRead) }} + remoteRead: +{{- if .Values.prometheus.prometheusSpec.remoteRead }} +{{ tpl (toYaml .Values.prometheus.prometheusSpec.remoteRead | indent 4) . }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.additionalRemoteRead }} +{{ toYaml .Values.prometheus.prometheusSpec.additionalRemoteRead | indent 4 }} +{{- end }} +{{- end }} +{{- if (or .Values.prometheus.prometheusSpec.remoteWrite .Values.prometheus.prometheusSpec.additionalRemoteWrite) }} + remoteWrite: +{{- if .Values.prometheus.prometheusSpec.remoteWrite }} +{{ tpl (toYaml .Values.prometheus.prometheusSpec.remoteWrite | indent 4) . }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.additionalRemoteWrite }} +{{ toYaml .Values.prometheus.prometheusSpec.additionalRemoteWrite | indent 4 }} +{{- end }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.securityContext }} + securityContext: +{{ toYaml .Values.prometheus.prometheusSpec.securityContext | indent 4 }} +{{- end }} +{{- if not .Values.prometheus.agentMode }} +{{- if .Values.prometheus.prometheusSpec.ruleNamespaceSelector }} + ruleNamespaceSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.ruleNamespaceSelector | indent 4) . }} +{{ else }} + ruleNamespaceSelector: {} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.ruleSelector }} + ruleSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.ruleSelector | indent 4) . }} +{{- else if .Values.prometheus.prometheusSpec.ruleSelectorNilUsesHelmValues }} + ruleSelector: + matchLabels: + release: {{ $.Release.Name | quote }} +{{ else }} + ruleSelector: {} +{{- end }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.scrapeConfigSelector }} + scrapeConfigSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.scrapeConfigSelector | indent 4) . }} +{{ else if .Values.prometheus.prometheusSpec.scrapeConfigSelectorNilUsesHelmValues }} + scrapeConfigSelector: + matchLabels: + release: {{ $.Release.Name | quote }} +{{ else }} + scrapeConfigSelector: {} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.scrapeConfigNamespaceSelector }} + scrapeConfigNamespaceSelector: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.scrapeConfigNamespaceSelector | indent 4) . }} +{{ else }} + scrapeConfigNamespaceSelector: {} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.storageSpec }} + storage: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.storageSpec | indent 4) . }} +{{- end }} +{{- with .Values.prometheus.prometheusSpec.persistentVolumeClaimRetentionPolicy }} + persistentVolumeClaimRetentionPolicy: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.podMetadata }} + podMetadata: +{{ tpl (toYaml .Values.prometheus.prometheusSpec.podMetadata | indent 4) . }} +{{- end }} +{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.query }} + query: +{{ toYaml .Values.prometheus.prometheusSpec.query | indent 4}} +{{- end }} +{{- if or .Values.prometheus.prometheusSpec.podAntiAffinity .Values.prometheus.prometheusSpec.affinity }} + affinity: +{{- if .Values.prometheus.prometheusSpec.affinity }} +{{ toYaml .Values.prometheus.prometheusSpec.affinity | indent 4 }} +{{- end }} +{{- if eq .Values.prometheus.prometheusSpec.podAntiAffinity "hard" }} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: {{ .Values.prometheus.prometheusSpec.podAntiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - {key: app.kubernetes.io/name, operator: In, values: [prometheus]} + - {key: prometheus, operator: In, values: [{{ template "kube-prometheus-stack.prometheus.crname" . }}]} +{{- else if eq .Values.prometheus.prometheusSpec.podAntiAffinity "soft" }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: {{ .Values.prometheus.prometheusSpec.podAntiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - {key: app.kubernetes.io/name, operator: In, values: [prometheus]} + - {key: prometheus, operator: In, values: [{{ template "kube-prometheus-stack.prometheus.crname" . }}]} +{{- end }} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 4 }} +{{- if .Values.prometheus.prometheusSpec.tolerations }} +{{ toYaml .Values.prometheus.prometheusSpec.tolerations | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.prometheus.prometheusSpec.topologySpreadConstraints | indent 4 }} +{{- end }} +{{- if .Values.global.imagePullSecrets }} + imagePullSecrets: +{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.additionalScrapeConfigs }} + additionalScrapeConfigs: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-scrape-confg + key: additional-scrape-configs.yaml +{{- end }} +{{- if .Values.prometheus.prometheusSpec.additionalScrapeConfigsSecret.enabled }} + additionalScrapeConfigs: + name: {{ .Values.prometheus.prometheusSpec.additionalScrapeConfigsSecret.name }} + key: {{ .Values.prometheus.prometheusSpec.additionalScrapeConfigsSecret.key }} +{{- end }} +{{- if not .Values.prometheus.agentMode }} +{{- if or .Values.prometheus.prometheusSpec.additionalAlertManagerConfigs .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret }} + additionalAlertManagerConfigs: +{{- if .Values.prometheus.prometheusSpec.additionalAlertManagerConfigs }} + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-am-confg + key: additional-alertmanager-configs.yaml +{{- end }} +{{- if .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret }} + name: {{ .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret.name }} + key: {{ .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret.key }} + {{- if hasKey .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret "optional" }} + optional: {{ .Values.prometheus.prometheusSpec.additionalAlertManagerConfigsSecret.optional }} + {{- end }} +{{- end }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigs }} + additionalAlertRelabelConfigs: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-am-relabel-confg + key: additional-alert-relabel-configs.yaml +{{- end }} +{{- if .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigsSecret }} + additionalAlertRelabelConfigs: + name: {{ .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigsSecret.name }} + key: {{ .Values.prometheus.prometheusSpec.additionalAlertRelabelConfigsSecret.key }} +{{- end }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.containers }} + containers: +{{ tpl .Values.prometheus.prometheusSpec.containers $ | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.initContainers }} + initContainers: +{{ toYaml .Values.prometheus.prometheusSpec.initContainers | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.priorityClassName }} + priorityClassName: {{ .Values.prometheus.prometheusSpec.priorityClassName }} +{{- end }} +{{- if not .Values.prometheus.agentMode }} +{{- if .Values.prometheus.prometheusSpec.thanos }} + thanos: +{{- with (omit .Values.prometheus.prometheusSpec.thanos "objectStorageConfig")}} +{{ toYaml . | indent 4 }} +{{- end }} +{{- if ((.Values.prometheus.prometheusSpec.thanos.objectStorageConfig).existingSecret) }} + objectStorageConfig: + key: "{{.Values.prometheus.prometheusSpec.thanos.objectStorageConfig.existingSecret.key }}" + name: "{{.Values.prometheus.prometheusSpec.thanos.objectStorageConfig.existingSecret.name }}" +{{- else if ((.Values.prometheus.prometheusSpec.thanos.objectStorageConfig).secret) }} + objectStorageConfig: + key: object-storage-configs.yaml + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus +{{- end }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.disableCompaction }} + disableCompaction: {{ .Values.prometheus.prometheusSpec.disableCompaction }} +{{- end }} +{{- end }} + portName: {{ .Values.prometheus.prometheusSpec.portName }} +{{- if .Values.prometheus.prometheusSpec.volumes }} + volumes: +{{ toYaml .Values.prometheus.prometheusSpec.volumes | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.volumeMounts }} + volumeMounts: +{{ toYaml .Values.prometheus.prometheusSpec.volumeMounts | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.arbitraryFSAccessThroughSMs }} + arbitraryFSAccessThroughSMs: +{{ toYaml .Values.prometheus.prometheusSpec.arbitraryFSAccessThroughSMs | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.overrideHonorLabels }} + overrideHonorLabels: {{ .Values.prometheus.prometheusSpec.overrideHonorLabels }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.overrideHonorTimestamps }} + overrideHonorTimestamps: {{ .Values.prometheus.prometheusSpec.overrideHonorTimestamps }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} + ignoreNamespaceSelectors: {{ .Values.prometheus.prometheusSpec.ignoreNamespaceSelectors }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enforcedNamespaceLabel }} + enforcedNamespaceLabel: {{ .Values.prometheus.prometheusSpec.enforcedNamespaceLabel }} +{{- $prometheusDefaultRulesExcludedFromEnforce := (include "rules.names" .) | fromYaml }} +{{- if not .Values.prometheus.agentMode }} + prometheusRulesExcludedFromEnforce: +{{- range $prometheusDefaultRulesExcludedFromEnforce.rules }} + - ruleNamespace: "{{ template "kube-prometheus-stack.namespace" $ }}" + ruleName: "{{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) . | trunc 63 | trimSuffix "-" }}" +{{- end }} +{{- if .Values.prometheus.prometheusSpec.prometheusRulesExcludedFromEnforce }} +{{ toYaml .Values.prometheus.prometheusSpec.prometheusRulesExcludedFromEnforce | indent 4 }} +{{- end }} +{{- end }} + excludedFromEnforcement: +{{- range $prometheusDefaultRulesExcludedFromEnforce.rules }} + - group: monitoring.coreos.com + resource: prometheusrules + namespace: "{{ template "kube-prometheus-stack.namespace" $ }}" + name: "{{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) . | trunc 63 | trimSuffix "-" }}" +{{- end }} +{{- if .Values.prometheus.prometheusSpec.excludedFromEnforcement }} +{{ tpl (toYaml .Values.prometheus.prometheusSpec.excludedFromEnforcement | indent 4) . }} +{{- end }} +{{- end }} +{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.queryLogFile }} + queryLogFile: {{ .Values.prometheus.prometheusSpec.queryLogFile }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.sampleLimit }} + sampleLimit: {{ .Values.prometheus.prometheusSpec.sampleLimit }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enforcedKeepDroppedTargets }} + enforcedKeepDroppedTargets: {{ .Values.prometheus.prometheusSpec.enforcedKeepDroppedTargets }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enforcedSampleLimit }} + enforcedSampleLimit: {{ .Values.prometheus.prometheusSpec.enforcedSampleLimit }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enforcedTargetLimit }} + enforcedTargetLimit: {{ .Values.prometheus.prometheusSpec.enforcedTargetLimit }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enforcedLabelLimit }} + enforcedLabelLimit: {{ .Values.prometheus.prometheusSpec.enforcedLabelLimit }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enforcedLabelNameLengthLimit }} + enforcedLabelNameLengthLimit: {{ .Values.prometheus.prometheusSpec.enforcedLabelNameLengthLimit }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.enforcedLabelValueLengthLimit}} + enforcedLabelValueLengthLimit: {{ .Values.prometheus.prometheusSpec.enforcedLabelValueLengthLimit }} +{{- end }} +{{- if and (not .Values.prometheus.agentMode) .Values.prometheus.prometheusSpec.allowOverlappingBlocks }} + allowOverlappingBlocks: {{ .Values.prometheus.prometheusSpec.allowOverlappingBlocks }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.minReadySeconds }} + minReadySeconds: {{ .Values.prometheus.prometheusSpec.minReadySeconds }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.maximumStartupDurationSeconds }} + maximumStartupDurationSeconds: {{ .Values.prometheus.prometheusSpec.maximumStartupDurationSeconds }} +{{- end }} + hostNetwork: {{ .Values.prometheus.prometheusSpec.hostNetwork }} +{{- if .Values.prometheus.prometheusSpec.hostAliases }} + hostAliases: +{{ toYaml .Values.prometheus.prometheusSpec.hostAliases | indent 4 }} +{{- end }} +{{- if .Values.prometheus.prometheusSpec.tracingConfig }} + tracingConfig: +{{ toYaml .Values.prometheus.prometheusSpec.tracingConfig | indent 4 }} +{{- end }} +{{- with .Values.prometheus.prometheusSpec.additionalConfig }} + {{- tpl (toYaml .) $ | nindent 2 }} +{{- end }} +{{- with .Values.prometheus.prometheusSpec.additionalConfigString }} + {{- tpl . $ | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp-clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp-clusterrole.yaml new file mode 100644 index 0000000000..872feb6066 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp-clusterrole.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.prometheus.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-psp + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +rules: +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} +- apiGroups: ['policy'] +{{- else }} +- apiGroups: ['extensions'] +{{- end }} + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-prometheus-stack.fullname" . }}-prometheus +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp-clusterrolebinding.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp-clusterrolebinding.yaml new file mode 100644 index 0000000000..50e3617704 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.prometheus.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-psp + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus-psp +subjects: + - kind: ServiceAccount + name: {{ template "kube-prometheus-stack.prometheus.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp.yaml new file mode 100644 index 0000000000..b53808daa5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/psp.yaml @@ -0,0 +1,58 @@ +{{- if and .Values.prometheus.enabled .Values.global.rbac.create .Values.global.rbac.pspEnabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{- if .Values.global.rbac.pspAnnotations }} + annotations: +{{ toYaml .Values.global.rbac.pspAnnotations | indent 4 }} +{{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' +{{- if .Values.prometheus.podSecurityPolicy.volumes }} +{{ toYaml .Values.prometheus.podSecurityPolicy.volumes | indent 4 }} +{{- end }} + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Permits the container to run with root privileges as well. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Allow adding the root group. + - min: 0 + max: 65535 + readOnlyRootFilesystem: false +{{- if .Values.prometheus.podSecurityPolicy.allowedCapabilities }} + allowedCapabilities: +{{ toYaml .Values.prometheus.podSecurityPolicy.allowedCapabilities | indent 4 }} +{{- end }} +{{- if .Values.prometheus.podSecurityPolicy.allowedHostPaths }} + allowedHostPaths: +{{ toYaml .Values.prometheus.podSecurityPolicy.allowedHostPaths | indent 4 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/alertmanager.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/alertmanager.rules.yaml new file mode 100644 index 0000000000..2d432c8f3a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/alertmanager.rules.yaml @@ -0,0 +1,305 @@ +{{- /* +Generated from 'alertmanager.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.alertmanager }} +{{- $alertmanagerJob := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "alertmanager" }} +{{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} +{{- if and .Values.alertmanager.enabled .Values.alertmanager.serviceMonitor.selfMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "alertmanager.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: alertmanager.rules + rules: +{{- if not (.Values.defaultRules.disabled.AlertmanagerFailedReload | default false) }} + - alert: AlertmanagerFailedReload + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} +{{- end }} + description: Configuration has failed to load for {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod{{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerfailedreload + summary: Reloading an Alertmanager configuration has failed. + expr: |- + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + max_over_time(alertmanager_config_last_reload_successful{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) == 0 + for: {{ dig "AlertmanagerFailedReload" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "AlertmanagerFailedReload" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.AlertmanagerMembersInconsistent | default false) }} + - alert: AlertmanagerMembersInconsistent + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} +{{- end }} + description: Alertmanager {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod{{`}}`}} has only found {{`{{`}} $value {{`}}`}} members of the {{`{{`}}$labels.job{{`}}`}} cluster. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagermembersinconsistent + summary: A member of an Alertmanager cluster has not found all other cluster members. + expr: |- + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + max_over_time(alertmanager_cluster_members{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) + < on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) group_left + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) (max_over_time(alertmanager_cluster_members{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m])) + for: {{ dig "AlertmanagerMembersInconsistent" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "AlertmanagerMembersInconsistent" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.AlertmanagerFailedToSendAlerts | default false) }} + - alert: AlertmanagerFailedToSendAlerts + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} +{{- end }} + description: Alertmanager {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod{{`}}`}} failed to send {{`{{`}} $value | humanizePercentage {{`}}`}} of notifications to {{`{{`}} $labels.integration {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerfailedtosendalerts + summary: An Alertmanager instance failed to send notifications. + expr: |- + ( + rate(alertmanager_notifications_failed_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) + / + ignoring (reason) group_left rate(alertmanager_notifications_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) + ) + > 0.01 + for: {{ dig "AlertmanagerFailedToSendAlerts" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "AlertmanagerFailedToSendAlerts" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.AlertmanagerClusterFailedToSendAlerts | default false) }} + - alert: AlertmanagerClusterFailedToSendAlerts + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} +{{- end }} + description: The minimum notification failure rate to {{`{{`}} $labels.integration {{`}}`}} sent from any instance in the {{`{{`}}$labels.job{{`}}`}} cluster is {{`{{`}} $value | humanizePercentage {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerclusterfailedtosendalerts + summary: All Alertmanager instances in a cluster failed to send notifications to a critical integration. + expr: |- + min by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service, integration) ( + rate(alertmanager_notifications_failed_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}", integration=~`.*`}[5m]) + / + ignoring (reason) group_left rate(alertmanager_notifications_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}", integration=~`.*`}[5m]) + ) + > 0.01 + for: {{ dig "AlertmanagerClusterFailedToSendAlerts" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "AlertmanagerClusterFailedToSendAlerts" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.AlertmanagerClusterFailedToSendAlerts | default false) }} + - alert: AlertmanagerClusterFailedToSendAlerts + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} +{{- end }} + description: The minimum notification failure rate to {{`{{`}} $labels.integration {{`}}`}} sent from any instance in the {{`{{`}}$labels.job{{`}}`}} cluster is {{`{{`}} $value | humanizePercentage {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerclusterfailedtosendalerts + summary: All Alertmanager instances in a cluster failed to send notifications to a non-critical integration. + expr: |- + min by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service, integration) ( + rate(alertmanager_notifications_failed_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}", integration!~`.*`}[5m]) + / + ignoring (reason) group_left rate(alertmanager_notifications_total{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}", integration!~`.*`}[5m]) + ) + > 0.01 + for: {{ dig "AlertmanagerClusterFailedToSendAlerts" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "AlertmanagerClusterFailedToSendAlerts" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.AlertmanagerConfigInconsistent | default false) }} + - alert: AlertmanagerConfigInconsistent + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} +{{- end }} + description: Alertmanager instances within the {{`{{`}}$labels.job{{`}}`}} cluster have different configurations. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerconfiginconsistent + summary: Alertmanager instances within the same cluster have different configurations. + expr: |- + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( + count_values by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ("config_hash", alertmanager_config_hash{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}) + ) + != 1 + for: {{ dig "AlertmanagerConfigInconsistent" "for" "20m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "AlertmanagerConfigInconsistent" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.AlertmanagerClusterDown | default false) }} + - alert: AlertmanagerClusterDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} +{{- end }} + description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of Alertmanager instances within the {{`{{`}}$labels.job{{`}}`}} cluster have been up for less than half of the last 5m.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerclusterdown + summary: Half or more of the Alertmanager instances within the same cluster are down. + expr: |- + ( + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( + avg_over_time(up{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[5m]) < 0.5 + ) + / + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( + up{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"} + ) + ) + >= 0.5 + for: {{ dig "AlertmanagerClusterDown" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "AlertmanagerClusterDown" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.AlertmanagerClusterCrashlooping | default false) }} + - alert: AlertmanagerClusterCrashlooping + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.alertmanager | indent 8 }} +{{- end }} + description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of Alertmanager instances within the {{`{{`}}$labels.job{{`}}`}} cluster have restarted at least 5 times in the last 10m.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/alertmanager/alertmanagerclustercrashlooping + summary: Half or more of the Alertmanager instances within the same cluster are crashlooping. + expr: |- + ( + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( + changes(process_start_time_seconds{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"}[10m]) > 4 + ) + / + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace,service,cluster) ( + up{job="{{ $alertmanagerJob }}",namespace="{{ $namespace }}"} + ) + ) + >= 0.5 + for: {{ dig "AlertmanagerClusterCrashlooping" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "AlertmanagerClusterCrashlooping" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.alertmanager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/config-reloaders.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/config-reloaders.yaml new file mode 100644 index 0000000000..9f554c022f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/config-reloaders.yaml @@ -0,0 +1,57 @@ +{{- /* +Generated from 'config-reloaders' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.configReloaders }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "config-reloaders" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: config-reloaders + rules: +{{- if not (.Values.defaultRules.disabled.ConfigReloaderSidecarErrors | default false) }} + - alert: ConfigReloaderSidecarErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.configReloaders }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.configReloaders | indent 8 }} +{{- end }} + description: 'Errors encountered while the {{`{{`}}$labels.pod{{`}}`}} config-reloader sidecar attempts to sync config in {{`{{`}}$labels.namespace{{`}}`}} namespace. + + As a result, configuration for service running in {{`{{`}}$labels.pod{{`}}`}} may be stale and cannot be updated anymore.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/configreloadersidecarerrors + summary: config-reloader sidecar has not had a successful reload for 10m + expr: max_over_time(reloader_last_reload_successful{namespace=~".+"}[5m]) == 0 + for: {{ dig "ConfigReloaderSidecarErrors" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "ConfigReloaderSidecarErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.configReloaders }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.configReloaders }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/etcd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/etcd.yaml new file mode 100644 index 0000000000..a1d7a508f8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/etcd.yaml @@ -0,0 +1,461 @@ +{{- /* +Generated from 'etcd' group from https://github.com/etcd-io/etcd.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.etcd }} +{{- if (include "exporter.kubeEtcd.enabled" .)}} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "etcd" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: etcd + rules: +{{- if not (.Values.defaultRules.disabled.etcdMembersDown | default false) }} + - alert: etcdMembersDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": members are down ({{`{{`}} $value {{`}}`}}).' + summary: etcd cluster members are down. + expr: |- + max without (endpoint) ( + sum without (instance) (up{job=~".*etcd.*"} == bool 0) + or + count without (To) ( + sum without (instance) (rate(etcd_network_peer_sent_failures_total{job=~".*etcd.*"}[120s])) > 0.01 + ) + ) + > 0 + for: {{ dig "etcdMembersDown" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdMembersDown" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdInsufficientMembers | default false) }} + - alert: etcdInsufficientMembers + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": insufficient members ({{`{{`}} $value {{`}}`}}).' + summary: etcd cluster has insufficient number of members. + expr: sum(up{job=~".*etcd.*"} == bool 1) without (instance) < ((count(up{job=~".*etcd.*"}) without (instance) + 1) / 2) + for: {{ dig "etcdInsufficientMembers" "for" "3m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdInsufficientMembers" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdNoLeader | default false) }} + - alert: etcdNoLeader + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": member {{`{{`}} $labels.instance {{`}}`}} has no leader.' + summary: etcd cluster has no leader. + expr: etcd_server_has_leader{job=~".*etcd.*"} == 0 + for: {{ dig "etcdNoLeader" "for" "1m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdNoLeader" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdHighNumberOfLeaderChanges | default false) }} + - alert: etcdHighNumberOfLeaderChanges + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": {{`{{`}} $value {{`}}`}} leader changes within the last 15 minutes. Frequent elections may be a sign of insufficient resources, high network latency, or disruptions by other components and should be investigated.' + summary: etcd cluster has high number of leader changes. + expr: increase((max without (instance) (etcd_server_leader_changes_seen_total{job=~".*etcd.*"}) or 0*absent(etcd_server_leader_changes_seen_total{job=~".*etcd.*"}))[15m:1m]) >= 4 + for: {{ dig "etcdHighNumberOfLeaderChanges" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdHighNumberOfLeaderChanges" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdHighNumberOfFailedGRPCRequests | default false) }} + - alert: etcdHighNumberOfFailedGRPCRequests + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": {{`{{`}} $value {{`}}`}}% of requests for {{`{{`}} $labels.grpc_method {{`}}`}} failed on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' + summary: etcd cluster has high number of failed grpc requests. + expr: |- + 100 * sum(rate(grpc_server_handled_total{job=~".*etcd.*", grpc_code=~"Unknown|FailedPrecondition|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded"}[5m])) without (grpc_type, grpc_code) + / + sum(rate(grpc_server_handled_total{job=~".*etcd.*"}[5m])) without (grpc_type, grpc_code) + > 1 + for: {{ dig "etcdHighNumberOfFailedGRPCRequests" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdHighNumberOfFailedGRPCRequests" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdHighNumberOfFailedGRPCRequests | default false) }} + - alert: etcdHighNumberOfFailedGRPCRequests + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": {{`{{`}} $value {{`}}`}}% of requests for {{`{{`}} $labels.grpc_method {{`}}`}} failed on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' + summary: etcd cluster has high number of failed grpc requests. + expr: |- + 100 * sum(rate(grpc_server_handled_total{job=~".*etcd.*", grpc_code=~"Unknown|FailedPrecondition|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded"}[5m])) without (grpc_type, grpc_code) + / + sum(rate(grpc_server_handled_total{job=~".*etcd.*"}[5m])) without (grpc_type, grpc_code) + > 5 + for: {{ dig "etcdHighNumberOfFailedGRPCRequests" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdHighNumberOfFailedGRPCRequests" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdGRPCRequestsSlow | default false) }} + - alert: etcdGRPCRequestsSlow + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": 99th percentile of gRPC requests is {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}} for {{`{{`}} $labels.grpc_method {{`}}`}} method.' + summary: etcd grpc requests are slow + expr: |- + histogram_quantile(0.99, sum(rate(grpc_server_handling_seconds_bucket{job=~".*etcd.*", grpc_method!="Defragment", grpc_type="unary"}[5m])) without(grpc_type)) + > 0.15 + for: {{ dig "etcdGRPCRequestsSlow" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdGRPCRequestsSlow" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdMemberCommunicationSlow | default false) }} + - alert: etcdMemberCommunicationSlow + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": member communication with {{`{{`}} $labels.To {{`}}`}} is taking {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' + summary: etcd cluster member communication is slow. + expr: |- + histogram_quantile(0.99, rate(etcd_network_peer_round_trip_time_seconds_bucket{job=~".*etcd.*"}[5m])) + > 0.15 + for: {{ dig "etcdMemberCommunicationSlow" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdMemberCommunicationSlow" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdHighNumberOfFailedProposals | default false) }} + - alert: etcdHighNumberOfFailedProposals + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": {{`{{`}} $value {{`}}`}} proposal failures within the last 30 minutes on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' + summary: etcd cluster has high number of proposal failures. + expr: rate(etcd_server_proposals_failed_total{job=~".*etcd.*"}[15m]) > 5 + for: {{ dig "etcdHighNumberOfFailedProposals" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdHighNumberOfFailedProposals" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdHighFsyncDurations | default false) }} + - alert: etcdHighFsyncDurations + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": 99th percentile fsync durations are {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' + summary: etcd cluster 99th percentile fsync durations are too high. + expr: |- + histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket{job=~".*etcd.*"}[5m])) + > 0.5 + for: {{ dig "etcdHighFsyncDurations" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdHighFsyncDurations" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdHighFsyncDurations | default false) }} + - alert: etcdHighFsyncDurations + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": 99th percentile fsync durations are {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' + summary: etcd cluster 99th percentile fsync durations are too high. + expr: |- + histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket{job=~".*etcd.*"}[5m])) + > 1 + for: {{ dig "etcdHighFsyncDurations" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdHighFsyncDurations" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdHighCommitDurations | default false) }} + - alert: etcdHighCommitDurations + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": 99th percentile commit durations {{`{{`}} $value {{`}}`}}s on etcd instance {{`{{`}} $labels.instance {{`}}`}}.' + summary: etcd cluster 99th percentile commit durations are too high. + expr: |- + histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket{job=~".*etcd.*"}[5m])) + > 0.25 + for: {{ dig "etcdHighCommitDurations" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdHighCommitDurations" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdDatabaseQuotaLowSpace | default false) }} + - alert: etcdDatabaseQuotaLowSpace + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": database size exceeds the defined quota on etcd instance {{`{{`}} $labels.instance {{`}}`}}, please defrag or increase the quota as the writes to etcd will be disabled when it is full.' + summary: etcd cluster database is running full. + expr: (last_over_time(etcd_mvcc_db_total_size_in_bytes{job=~".*etcd.*"}[5m]) / last_over_time(etcd_server_quota_backend_bytes{job=~".*etcd.*"}[5m]))*100 > 95 + for: {{ dig "etcdDatabaseQuotaLowSpace" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdDatabaseQuotaLowSpace" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdExcessiveDatabaseGrowth | default false) }} + - alert: etcdExcessiveDatabaseGrowth + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": Predicting running out of disk space in the next four hours, based on write observations within the past four hours on etcd instance {{`{{`}} $labels.instance {{`}}`}}, please check as it might be disruptive.' + summary: etcd cluster database growing very fast. + expr: predict_linear(etcd_mvcc_db_total_size_in_bytes{job=~".*etcd.*"}[4h], 4*60*60) > etcd_server_quota_backend_bytes{job=~".*etcd.*"} + for: {{ dig "etcdExcessiveDatabaseGrowth" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdExcessiveDatabaseGrowth" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.etcdDatabaseHighFragmentationRatio | default false) }} + - alert: etcdDatabaseHighFragmentationRatio + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.etcd }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.etcd | indent 8 }} +{{- end }} + description: 'etcd cluster "{{`{{`}} $labels.job {{`}}`}}": database size in use on instance {{`{{`}} $labels.instance {{`}}`}} is {{`{{`}} $value | humanizePercentage {{`}}`}} of the actual allocated disk space, please run defragmentation (e.g. etcdctl defrag) to retrieve the unused fragmented disk space.' + runbook_url: https://etcd.io/docs/v3.5/op-guide/maintenance/#defragmentation + summary: etcd database size in use is less than 50% of the actual allocated storage. + expr: (last_over_time(etcd_mvcc_db_total_size_in_use_in_bytes{job=~".*etcd.*"}[5m]) / last_over_time(etcd_mvcc_db_total_size_in_bytes{job=~".*etcd.*"}[5m])) < 0.5 and etcd_mvcc_db_total_size_in_use_in_bytes{job=~".*etcd.*"} > 104857600 + for: {{ dig "etcdDatabaseHighFragmentationRatio" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "etcdDatabaseHighFragmentationRatio" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.etcd }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/general.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/general.rules.yaml new file mode 100644 index 0000000000..6324228838 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/general.rules.yaml @@ -0,0 +1,125 @@ +{{- /* +Generated from 'general.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.general }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "general.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: general.rules + rules: +{{- if not (.Values.defaultRules.disabled.TargetDown | default false) }} + - alert: TargetDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.general }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.general | indent 8 }} +{{- end }} + description: '{{`{{`}} printf "%.4g" $value {{`}}`}}% of the {{`{{`}} $labels.job {{`}}`}}/{{`{{`}} $labels.service {{`}}`}} targets in {{`{{`}} $labels.namespace {{`}}`}} namespace are down.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/general/targetdown + summary: One or more targets are unreachable. + expr: 100 * (count(up == 0) BY (cluster, job, namespace, service) / count(up) BY (cluster, job, namespace, service)) > 10 + for: {{ dig "TargetDown" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "TargetDown" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.general }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.general }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.Watchdog | default false) }} + - alert: Watchdog + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.general }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.general | indent 8 }} +{{- end }} + description: 'This is an alert meant to ensure that the entire alerting pipeline is functional. + + This alert is always firing, therefore it should always be firing in Alertmanager + + and always fire against a receiver. There are integrations with various notification + + mechanisms that send a notification when this alert is not firing. For example the + + "DeadMansSnitch" integration in PagerDuty. + + ' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/general/watchdog + summary: An alert that should always be firing to certify that Alertmanager is working properly. + expr: vector(1) + labels: + severity: {{ dig "Watchdog" "severity" "none" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.general }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.general }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.InfoInhibitor | default false) }} + - alert: InfoInhibitor + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.general }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.general | indent 8 }} +{{- end }} + description: 'This is an alert that is used to inhibit info alerts. + + By themselves, the info-level alerts are sometimes very noisy, but they are relevant when combined with + + other alerts. + + This alert fires whenever there''s a severity="info" alert, and stops firing when another alert with a + + severity of ''warning'' or ''critical'' starts firing on the same namespace. + + This alert should be routed to a null receiver and configured to inhibit alerts with severity="info". + + ' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/general/infoinhibitor + summary: Info-level alert inhibition. + expr: ALERTS{severity = "info"} == 1 unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace) ALERTS{alertname != "InfoInhibitor", severity =~ "warning|critical", alertstate="firing"} == 1 + labels: + severity: {{ dig "InfoInhibitor" "severity" "none" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.general }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.general }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml new file mode 100644 index 0000000000..19aa6b4e25 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_cpu_usage_seconds_total.yaml @@ -0,0 +1,43 @@ +{{- /* +Generated from 'k8s.rules.container-cpu-usage-seconds-total' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerCpuUsageSecondsTotal }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-cpu-usage-seconds-total" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: k8s.rules.container_cpu_usage_seconds_total + rules: + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, container) ( + irate(container_cpu_usage_seconds_total{job="kubelet", metrics_path="/metrics/cadvisor", image!=""}[5m]) + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) ( + 1, max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerCpuUsageSecondsTotal }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerCpuUsageSecondsTotal }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml new file mode 100644 index 0000000000..2a08f43838 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_cache.yaml @@ -0,0 +1,42 @@ +{{- /* +Generated from 'k8s.rules.container-memory-cache' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerMemoryCache }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-memory-cache" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: k8s.rules.container_memory_cache + rules: + - expr: |- + container_memory_cache{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_cache + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryCache }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryCache }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml new file mode 100644 index 0000000000..85b23faafa --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_rss.yaml @@ -0,0 +1,42 @@ +{{- /* +Generated from 'k8s.rules.container-memory-rss' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerMemoryRss }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-memory-rss" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: k8s.rules.container_memory_rss + rules: + - expr: |- + container_memory_rss{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_rss + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryRss }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryRss }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml new file mode 100644 index 0000000000..aae26802ed --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_swap.yaml @@ -0,0 +1,42 @@ +{{- /* +Generated from 'k8s.rules.container-memory-swap' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerMemorySwap }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-memory-swap" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: k8s.rules.container_memory_swap + rules: + - expr: |- + container_memory_swap{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_swap + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemorySwap }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemorySwap }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml new file mode 100644 index 0000000000..cc7fbbd063 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_memory_working_set_bytes.yaml @@ -0,0 +1,42 @@ +{{- /* +Generated from 'k8s.rules.container-memory-working-set-bytes' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerMemoryWorkingSetBytes }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-memory-working-set-bytes" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: k8s.rules.container_memory_working_set_bytes + rules: + - expr: |- + container_memory_working_set_bytes{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_working_set_bytes + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryWorkingSetBytes }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerMemoryWorkingSetBytes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml new file mode 100644 index 0000000000..edba0c2e01 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.container_resource.yaml @@ -0,0 +1,168 @@ +{{- /* +Generated from 'k8s.rules.container-resource' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sContainerResource }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.container-resource" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: k8s.rules.container_resource + rules: + - expr: |- + kube_pod_container_resource_requests{resource="memory",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) + group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_memory:active:kube_pod_container_resource_requests + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, cluster) ( + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) ( + kube_pod_container_resource_requests{resource="memory",job="{{ $kubeStateMetricsJob }}"} + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_memory:kube_pod_container_resource_requests:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + kube_pod_container_resource_requests{resource="cpu",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) + group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, cluster) ( + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) ( + kube_pod_container_resource_requests{resource="cpu",job="{{ $kubeStateMetricsJob }}"} + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_cpu:kube_pod_container_resource_requests:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + kube_pod_container_resource_limits{resource="memory",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) + group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_memory:active:kube_pod_container_resource_limits + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, cluster) ( + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) ( + kube_pod_container_resource_limits{resource="memory",job="{{ $kubeStateMetricsJob }}"} + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_memory:kube_pod_container_resource_limits:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + kube_pod_container_resource_limits{resource="cpu",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) + group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, cluster) ( + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) ( + kube_pod_container_resource_limits{resource="cpu",job="{{ $kubeStateMetricsJob }}"} + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left() max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_cpu:kube_pod_container_resource_limits:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sContainerResource }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml new file mode 100644 index 0000000000..43207a748c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.pod_owner.yaml @@ -0,0 +1,107 @@ +{{- /* +Generated from 'k8s.rules.pod-owner' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8sPodOwner }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules.pod-owner" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: k8s.rules.pod_owner + rules: + - expr: |- + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, workload, pod) ( + label_replace( + label_replace( + kube_pod_owner{job="{{ $kubeStateMetricsJob }}", owner_kind="ReplicaSet"}, + "replicaset", "$1", "owner_name", "(.*)" + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}replicaset, namespace) group_left(owner_name) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}replicaset, namespace) ( + 1, max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}replicaset, namespace, owner_name) ( + kube_replicaset_owner{job="{{ $kubeStateMetricsJob }}"} + ) + ), + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: deployment + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: |- + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="{{ $kubeStateMetricsJob }}", owner_kind="DaemonSet"}, + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: daemonset + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: |- + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="{{ $kubeStateMetricsJob }}", owner_kind="StatefulSet"}, + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: statefulset + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: |- + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="{{ $kubeStateMetricsJob }}", owner_kind="Job"}, + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: job + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.k8sPodOwner }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: namespace_workload_pod:kube_pod_owner:relabel +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.yaml new file mode 100644 index 0000000000..c61bd222ab --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/k8s.rules.yaml @@ -0,0 +1,237 @@ +{{- /* +Generated from 'k8s.rules' group from https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/main/manifests/kubernetesControlPlane-prometheusRule.yaml +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.k8s }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "k8s.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: k8s.rules + rules: + - expr: |- + sum by (cluster, namespace, pod, container) ( + irate(container_cpu_usage_seconds_total{job="{{ include "exporter.kubelet.jobName" . }}", metrics_path="/metrics/cadvisor", image!=""}[5m]) + ) * on (cluster, namespace, pod) group_left(node) topk by (cluster, namespace, pod) ( + 1, max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + container_memory_working_set_bytes{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, + max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_working_set_bytes + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + container_memory_rss{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, + max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_rss + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + container_memory_cache{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, + max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_cache + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + container_memory_swap{job="kubelet", metrics_path="/metrics/cadvisor", image!=""} + * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1, + max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}) + ) + record: node_namespace_pod_container:container_memory_swap + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + kube_pod_container_resource_requests{resource="memory",job="kube-state-metrics"} * on (namespace, pod, cluster) + group_left() max by (namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_memory:active:kube_pod_container_resource_requests + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + sum by (namespace, cluster) ( + sum by (namespace, pod, cluster) ( + max by (namespace, pod, container, cluster) ( + kube_pod_container_resource_requests{resource="memory",job="kube-state-metrics"} + ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_memory:kube_pod_container_resource_requests:sum + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} * on (namespace, pod, cluster) + group_left() max by (namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + sum by (namespace, cluster) ( + sum by (namespace, pod, cluster) ( + max by (namespace, pod, container, cluster) ( + kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} + ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_cpu:kube_pod_container_resource_requests:sum + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + kube_pod_container_resource_limits{resource="memory",job="kube-state-metrics"} * on (namespace, pod, cluster) + group_left() max by (namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_memory:active:kube_pod_container_resource_limits + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + sum by (namespace, cluster) ( + sum by (namespace, pod, cluster) ( + max by (namespace, pod, container, cluster) ( + kube_pod_container_resource_limits{resource="memory",job="kube-state-metrics"} + ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_memory:kube_pod_container_resource_limits:sum + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + kube_pod_container_resource_limits{resource="cpu",job="kube-state-metrics"} * on (namespace, pod, cluster) + group_left() max by (namespace, pod, cluster) ( + (kube_pod_status_phase{phase=~"Pending|Running"} == 1) + ) + record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + sum by (namespace, cluster) ( + sum by (namespace, pod, cluster) ( + max by (namespace, pod, container, cluster) ( + kube_pod_container_resource_limits{resource="cpu",job="kube-state-metrics"} + ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( + kube_pod_status_phase{phase=~"Pending|Running"} == 1 + ) + ) + ) + record: namespace_cpu:kube_pod_container_resource_limits:sum + {{- if .Values.defaultRules.additionalRuleLabels }} + labels: + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + - expr: |- + max by (cluster, namespace, workload, pod) ( + label_replace( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="ReplicaSet"}, + "replicaset", "$1", "owner_name", "(.*)" + ) * on(replicaset, namespace) group_left(owner_name) topk by(replicaset, namespace) ( + 1, max by (replicaset, namespace, owner_name) ( + kube_replicaset_owner{job="kube-state-metrics"} + ) + ), + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: deployment + {{- if .Values.defaultRules.additionalRuleLabels }} + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: |- + max by (cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="DaemonSet"}, + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: daemonset + {{- if .Values.defaultRules.additionalRuleLabels }} + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: |- + max by (cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="StatefulSet"}, + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: statefulset + {{- if .Values.defaultRules.additionalRuleLabels }} + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + record: namespace_workload_pod:kube_pod_owner:relabel + - expr: |- + max by (cluster, namespace, workload, pod) ( + label_replace( + kube_pod_owner{job="kube-state-metrics", owner_kind="Job"}, + "workload", "$1", "owner_name", "(.*)" + ) + ) + labels: + workload_type: job + {{- if .Values.defaultRules.additionalRuleLabels }} + {{ toYaml .Values.defaultRules.additionalRuleLabels | nindent 8 }} + {{- end }} + record: namespace_workload_pod:kube_pod_owner:relabel +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml new file mode 100644 index 0000000000..02c8e7adbf --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-availability.rules.yaml @@ -0,0 +1,273 @@ +{{- /* +Generated from 'kube-apiserver-availability.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeApiServer.enabled .Values.defaultRules.rules.kubeApiserverAvailability }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-apiserver-availability.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - interval: 3m + name: kube-apiserver-availability.rules + rules: + - expr: avg_over_time(code_verb:apiserver_request_total:increase1h[30d]) * 24 * 30 + record: code_verb:apiserver_request_total:increase30d + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code) (code_verb:apiserver_request_total:increase30d{verb=~"LIST|GET"}) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: code:apiserver_request_total:increase30d + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code) (code_verb:apiserver_request_total:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: code:apiserver_request_total:increase30d + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, verb, scope) (increase(apiserver_request_sli_duration_seconds_count{job="apiserver"}[1h])) + record: cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase1h + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, verb, scope) (avg_over_time(cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase1h[30d]) * 24 * 30) + record: cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, verb, scope, le) (increase(apiserver_request_sli_duration_seconds_bucket[1h])) + record: cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, verb, scope, le) (avg_over_time(cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h[30d]) * 24 * 30) + record: cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + 1 - ( + ( + # write too slow + sum by (cluster) (cluster_verb_scope:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) + - + sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"POST|PUT|PATCH|DELETE",le="1"}) + ) + + ( + # read too slow + sum by (cluster) (cluster_verb_scope:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count:increase30d{verb=~"LIST|GET"}) + - + ( + ( + sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope=~"resource|",le="1"}) + or + vector(0) + ) + + + sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="namespace",le="5"}) + + + sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="cluster",le="30"}) + ) + ) + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{code=~"5.."} or vector(0)) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d) + labels: + verb: all + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:availability30d + - expr: |- + 1 - ( + sum by (cluster) (cluster_verb_scope:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count:increase30d{verb=~"LIST|GET"}) + - + ( + # too slow + ( + sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope=~"resource|",le="1"}) + or + vector(0) + ) + + + sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="namespace",le="5"}) + + + sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"LIST|GET",scope="cluster",le="30"}) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{verb="read",code=~"5.."} or vector(0)) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{verb="read"}) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:availability30d + - expr: |- + 1 - ( + ( + # too slow + sum by (cluster) (cluster_verb_scope:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count:increase30d{verb=~"POST|PUT|PATCH|DELETE"}) + - + sum by (cluster) (cluster_verb_scope_le:apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket:increase30d{verb=~"POST|PUT|PATCH|DELETE",le="1"}) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{verb="write",code=~"5.."} or vector(0)) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (code:apiserver_request_total:increase30d{verb="write"}) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:availability30d + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,code,resource) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[5m])) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: code_resource:apiserver_request_total:rate5m + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,code,resource) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[5m])) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: code_resource:apiserver_request_total:rate5m + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"2.."}[1h])) + record: code_verb:apiserver_request_total:increase1h + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"3.."}[1h])) + record: code_verb:apiserver_request_total:increase1h + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"4.."}[1h])) + record: code_verb:apiserver_request_total:increase1h + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, code, verb) (increase(apiserver_request_total{job="apiserver",verb=~"LIST|GET|POST|PUT|PATCH|DELETE",code=~"5.."}[1h])) + record: code_verb:apiserver_request_total:increase1h + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverAvailability }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml new file mode 100644 index 0000000000..49f4400a59 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-burnrate.rules.yaml @@ -0,0 +1,440 @@ +{{- /* +Generated from 'kube-apiserver-burnrate.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeApiServer.enabled .Values.defaultRules.rules.kubeApiserverBurnrate }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-apiserver-burnrate.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kube-apiserver-burnrate.rules + rules: + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[1d])) + - + ( + ( + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[1d])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[1d])) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[1d])) + ) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[1d])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[1d])) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate1d + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[1h])) + - + ( + ( + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[1h])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[1h])) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[1h])) + ) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[1h])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[1h])) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate1h + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[2h])) + - + ( + ( + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[2h])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[2h])) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[2h])) + ) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[2h])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[2h])) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate2h + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[30m])) + - + ( + ( + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[30m])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[30m])) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[30m])) + ) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[30m])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[30m])) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate30m + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[3d])) + - + ( + ( + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[3d])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[3d])) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[3d])) + ) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[3d])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[3d])) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate3d + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[5m])) + - + ( + ( + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[5m])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[5m])) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[5m])) + ) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[5m])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[5m])) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate5m + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[6h])) + - + ( + ( + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope=~"resource|",le="1"}[6h])) + or + vector(0) + ) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="namespace",le="5"}[6h])) + + + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward",scope="cluster",le="30"}[6h])) + ) + ) + + + # errors + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET",code=~"5.."}[6h])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"LIST|GET"}[6h])) + labels: + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate6h + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[1d])) + - + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[1d])) + ) + + + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[1d])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[1d])) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate1d + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[1h])) + - + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[1h])) + ) + + + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[1h])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[1h])) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate1h + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[2h])) + - + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[2h])) + ) + + + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[2h])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[2h])) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate2h + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[30m])) + - + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[30m])) + ) + + + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[30m])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[30m])) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate30m + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[3d])) + - + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[3d])) + ) + + + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[3d])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[3d])) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate3d + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[5m])) + - + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[5m])) + ) + + + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[5m])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[5m])) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate5m + - expr: |- + ( + ( + # too slow + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_count{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[6h])) + - + sum by (cluster) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward",le="1"}[6h])) + ) + + + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",code=~"5.."}[6h])) + ) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(apiserver_request_total{job="apiserver",verb=~"POST|PUT|PATCH|DELETE"}[6h])) + labels: + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverBurnrate }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: apiserver_request:burnrate6h +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml new file mode 100644 index 0000000000..5d08aa4349 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-histogram.rules.yaml @@ -0,0 +1,53 @@ +{{- /* +Generated from 'kube-apiserver-histogram.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeApiServer.enabled .Values.defaultRules.rules.kubeApiserverHistogram }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-apiserver-histogram.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kube-apiserver-histogram.rules + rules: + - expr: histogram_quantile(0.99, sum by (cluster, le, resource) (rate(apiserver_request{{ if (semverCompare ">=1.23.0-0" $kubeTargetVersion) }}_slo{{ end }}_duration_seconds_bucket{job="apiserver",verb=~"LIST|GET",subresource!~"proxy|attach|log|exec|portforward"}[5m]))) > 0 + labels: + quantile: '0.99' + verb: read + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverHistogram }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverHistogram }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.99, sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, le, resource) (rate(apiserver_request_sli_duration_seconds_bucket{job="apiserver",verb=~"POST|PUT|PATCH|DELETE",subresource!~"proxy|attach|log|exec|portforward"}[5m]))) > 0 + labels: + quantile: '0.99' + verb: write + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverHistogram }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverHistogram }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml new file mode 100644 index 0000000000..a83cf9060c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-apiserver-slos.yaml @@ -0,0 +1,159 @@ +{{- /* +Generated from 'kube-apiserver-slos' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeApiServer.enabled .Values.defaultRules.rules.kubeApiserverSlos }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-apiserver-slos" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kube-apiserver-slos + rules: +{{- if not (.Values.defaultRules.disabled.KubeAPIErrorBudgetBurn | default false) }} + - alert: KubeAPIErrorBudgetBurn + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos | indent 8 }} +{{- end }} + description: The API server is burning too much error budget. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapierrorbudgetburn + summary: The API server is burning too much error budget. + expr: |- + sum(apiserver_request:burnrate1h) > (14.40 * 0.01000) + and + sum(apiserver_request:burnrate5m) > (14.40 * 0.01000) + for: {{ dig "KubeAPIErrorBudgetBurn" "for" "2m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + long: 1h + severity: {{ dig "KubeAPIErrorBudgetBurn" "severity" "critical" .Values.customRules }} + short: 5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeAPIErrorBudgetBurn | default false) }} + - alert: KubeAPIErrorBudgetBurn + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos | indent 8 }} +{{- end }} + description: The API server is burning too much error budget. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapierrorbudgetburn + summary: The API server is burning too much error budget. + expr: |- + sum(apiserver_request:burnrate6h) > (6.00 * 0.01000) + and + sum(apiserver_request:burnrate30m) > (6.00 * 0.01000) + for: {{ dig "KubeAPIErrorBudgetBurn" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + long: 6h + severity: {{ dig "KubeAPIErrorBudgetBurn" "severity" "critical" .Values.customRules }} + short: 30m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeAPIErrorBudgetBurn | default false) }} + - alert: KubeAPIErrorBudgetBurn + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos | indent 8 }} +{{- end }} + description: The API server is burning too much error budget. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapierrorbudgetburn + summary: The API server is burning too much error budget. + expr: |- + sum(apiserver_request:burnrate1d) > (3.00 * 0.01000) + and + sum(apiserver_request:burnrate2h) > (3.00 * 0.01000) + for: {{ dig "KubeAPIErrorBudgetBurn" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + long: 1d + severity: {{ dig "KubeAPIErrorBudgetBurn" "severity" "warning" .Values.customRules }} + short: 2h + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeAPIErrorBudgetBurn | default false) }} + - alert: KubeAPIErrorBudgetBurn + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeApiserverSlos | indent 8 }} +{{- end }} + description: The API server is burning too much error budget. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapierrorbudgetburn + summary: The API server is burning too much error budget. + expr: |- + sum(apiserver_request:burnrate3d) > (1.00 * 0.01000) + and + sum(apiserver_request:burnrate6h) > (1.00 * 0.01000) + for: {{ dig "KubeAPIErrorBudgetBurn" "for" "3h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + long: 3d + severity: {{ dig "KubeAPIErrorBudgetBurn" "severity" "warning" .Values.customRules }} + short: 6h + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeApiserverSlos }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml new file mode 100644 index 0000000000..fc199f11f8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-general.rules.yaml @@ -0,0 +1,49 @@ +{{- /* +Generated from 'kube-prometheus-general.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubePrometheusGeneral }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-prometheus-general.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kube-prometheus-general.rules + rules: + - expr: count without(instance, pod, node) (up == 1) + record: count:up1 + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusGeneral }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusGeneral }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: count without(instance, pod, node) (up == 0) + record: count:up0 + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusGeneral }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusGeneral }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml new file mode 100644 index 0000000000..63f721f42a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-prometheus-node-recording.rules.yaml @@ -0,0 +1,93 @@ +{{- /* +Generated from 'kube-prometheus-node-recording.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubePrometheusNodeRecording }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-prometheus-node-recording.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kube-prometheus-node-recording.rules + rules: + - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[3m])) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) + record: instance:node_cpu:rate:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum(rate(node_network_receive_bytes_total[3m])) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) + record: instance:node_network_receive_bytes:rate:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum(rate(node_network_transmit_bytes_total[3m])) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) + record: instance:node_network_transmit_bytes:rate:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[5m])) WITHOUT (cpu, mode) / ON ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) GROUP_LEFT() count(sum(node_cpu_seconds_total) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance, cpu)) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance) + record: instance:node_cpu:ratio + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal"}[5m])) + record: cluster:node_cpu:sum_rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: cluster:node_cpu:sum_rate5m / count(sum(node_cpu_seconds_total) BY ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance, cpu)) + record: cluster:node_cpu:ratio + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubePrometheusNodeRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml new file mode 100644 index 0000000000..9f8bf60228 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-scheduler.rules.yaml @@ -0,0 +1,135 @@ +{{- /* +Generated from 'kube-scheduler.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeScheduler.enabled .Values.defaultRules.rules.kubeSchedulerRecording }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-scheduler.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kube-scheduler.rules + rules: + - expr: histogram_quantile(0.99, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="{{ include "exporter.kubeScheduler.jobName" . }}"}[5m])) without(instance, pod)) + labels: + quantile: '0.99' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.99, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="{{ include "exporter.kubeScheduler.jobName" . }}"}[5m])) without(instance, pod)) + labels: + quantile: '0.99' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.99, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: '0.99' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.9, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: '0.9' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.9, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: '0.9' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.9, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: '0.9' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.5, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: '0.5' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.5, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: '0.5' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.5, sum(rate(scheduler_binding_duration_seconds_bucket{job="kube-scheduler"}[5m])) without(instance, pod)) + labels: + quantile: '0.5' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-state-metrics.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-state-metrics.yaml new file mode 100644 index 0000000000..7f3600fb71 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kube-state-metrics.yaml @@ -0,0 +1,152 @@ +{{- /* +Generated from 'kube-state-metrics' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubeStateMetrics }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kube-state-metrics" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kube-state-metrics + rules: +{{- if not (.Values.defaultRules.disabled.KubeStateMetricsListErrors | default false) }} + - alert: KubeStateMetricsListErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics | indent 8 }} +{{- end }} + description: kube-state-metrics is experiencing errors at an elevated rate in list operations. This is likely causing it to not be able to expose metrics about Kubernetes objects correctly or at all. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kube-state-metrics/kubestatemetricslisterrors + summary: kube-state-metrics is experiencing errors in list operations. + expr: |- + (sum(rate(kube_state_metrics_list_total{job="{{ $kubeStateMetricsJob }}",result="error"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) + / + sum(rate(kube_state_metrics_list_total{job="{{ $kubeStateMetricsJob }}"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) + > 0.01 + for: {{ dig "KubeStateMetricsListErrors" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeStateMetricsListErrors" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeStateMetricsWatchErrors | default false) }} + - alert: KubeStateMetricsWatchErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics | indent 8 }} +{{- end }} + description: kube-state-metrics is experiencing errors at an elevated rate in watch operations. This is likely causing it to not be able to expose metrics about Kubernetes objects correctly or at all. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kube-state-metrics/kubestatemetricswatcherrors + summary: kube-state-metrics is experiencing errors in watch operations. + expr: |- + (sum(rate(kube_state_metrics_watch_total{job="{{ $kubeStateMetricsJob }}",result="error"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) + / + sum(rate(kube_state_metrics_watch_total{job="{{ $kubeStateMetricsJob }}"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) + > 0.01 + for: {{ dig "KubeStateMetricsWatchErrors" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeStateMetricsWatchErrors" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeStateMetricsShardingMismatch | default false) }} + - alert: KubeStateMetricsShardingMismatch + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics | indent 8 }} +{{- end }} + description: kube-state-metrics pods are running with different --total-shards configuration, some Kubernetes objects may be exposed multiple times or not exposed at all. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kube-state-metrics/kubestatemetricsshardingmismatch + summary: kube-state-metrics sharding is misconfigured. + expr: stdvar (kube_state_metrics_total_shards{job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) != 0 + for: {{ dig "KubeStateMetricsShardingMismatch" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeStateMetricsShardingMismatch" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeStateMetricsShardsMissing | default false) }} + - alert: KubeStateMetricsShardsMissing + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeStateMetrics | indent 8 }} +{{- end }} + description: kube-state-metrics shards are missing, some Kubernetes objects are not being exposed. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kube-state-metrics/kubestatemetricsshardsmissing + summary: kube-state-metrics shards are missing. + expr: |- + 2^max(kube_state_metrics_total_shards{job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - 1 + - + sum( 2 ^ max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, shard_ordinal) (kube_state_metrics_shard_ordinal{job="{{ $kubeStateMetricsJob }}"}) ) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) + != 0 + for: {{ dig "KubeStateMetricsShardsMissing" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeStateMetricsShardsMissing" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeStateMetrics }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubelet.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubelet.rules.yaml new file mode 100644 index 0000000000..8cd03baa43 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubelet.rules.yaml @@ -0,0 +1,65 @@ +{{- /* +Generated from 'kubelet.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubelet }} +{{- if (include "exporter.kubelet.enabled" .)}} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubelet.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubelet.rules + rules: + - expr: histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, le) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) group_left(node) kubelet_node_name{job="kubelet", metrics_path="/metrics"}) + labels: + quantile: '0.99' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubelet }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubelet }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.9, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, le) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) group_left(node) kubelet_node_name{job="kubelet", metrics_path="/metrics"}) + labels: + quantile: '0.9' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubelet }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubelet }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile + - expr: histogram_quantile(0.5, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job="kubelet", metrics_path="/metrics"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, le) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) group_left(node) kubelet_node_name{job="kubelet", metrics_path="/metrics"}) + labels: + quantile: '0.5' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubelet }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubelet }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-apps.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-apps.yaml new file mode 100644 index 0000000000..76215b3999 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-apps.yaml @@ -0,0 +1,568 @@ +{{- /* +Generated from 'kubernetes-apps' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesApps }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +{{- $targetNamespace := .Values.defaultRules.appNamespacesTarget }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-apps" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-apps + rules: +{{- if not (.Values.defaultRules.disabled.KubePodCrashLooping | default false) }} + - alert: KubePodCrashLooping + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: 'Pod {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod {{`}}`}} ({{`{{`}} $labels.container {{`}}`}}) is in waiting state (reason: "CrashLoopBackOff").' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepodcrashlooping + summary: Pod is crash looping. + expr: max_over_time(kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff", job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[5m]) >= 1 + for: {{ dig "KubePodCrashLooping" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubePodCrashLooping" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubePodNotReady | default false) }} + - alert: KubePodNotReady + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: Pod {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod {{`}}`}} has been in a non-ready state for longer than 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepodnotready + summary: Pod has been in a non-ready state for more than 15 minutes. + expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + kube_pod_status_phase{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}", phase=~"Pending|Unknown|Failed"} + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) group_left(owner_kind) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, cluster) ( + 1, max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, owner_kind, cluster) (kube_pod_owner{owner_kind!="Job"}) + ) + ) > 0 + for: {{ dig "KubePodNotReady" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubePodNotReady" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeDeploymentGenerationMismatch | default false) }} + - alert: KubeDeploymentGenerationMismatch + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: Deployment generation for {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.deployment {{`}}`}} does not match, this indicates that the Deployment has failed but has not been rolled back. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedeploymentgenerationmismatch + summary: Deployment generation mismatch due to possible roll-back + expr: |- + kube_deployment_status_observed_generation{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + kube_deployment_metadata_generation{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + for: {{ dig "KubeDeploymentGenerationMismatch" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeDeploymentGenerationMismatch" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeDeploymentReplicasMismatch | default false) }} + - alert: KubeDeploymentReplicasMismatch + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: Deployment {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.deployment {{`}}`}} has not matched the expected number of replicas for longer than 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedeploymentreplicasmismatch + summary: Deployment has not matched the expected number of replicas. + expr: |- + ( + kube_deployment_spec_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + > + kube_deployment_status_replicas_available{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + ) and ( + changes(kube_deployment_status_replicas_updated{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[10m]) + == + 0 + ) + for: {{ dig "KubeDeploymentReplicasMismatch" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeDeploymentReplicasMismatch" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeDeploymentRolloutStuck | default false) }} + - alert: KubeDeploymentRolloutStuck + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: Rollout of deployment {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.deployment {{`}}`}} is not progressing for longer than 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedeploymentrolloutstuck + summary: Deployment rollout is not progressing. + expr: |- + kube_deployment_status_condition{condition="Progressing", status="false",job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != 0 + for: {{ dig "KubeDeploymentRolloutStuck" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeDeploymentRolloutStuck" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeStatefulSetReplicasMismatch | default false) }} + - alert: KubeStatefulSetReplicasMismatch + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: StatefulSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.statefulset {{`}}`}} has not matched the expected number of replicas for longer than 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubestatefulsetreplicasmismatch + summary: StatefulSet has not matched the expected number of replicas. + expr: |- + ( + kube_statefulset_status_replicas_ready{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + kube_statefulset_status_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + ) and ( + changes(kube_statefulset_status_replicas_updated{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[10m]) + == + 0 + ) + for: {{ dig "KubeStatefulSetReplicasMismatch" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeStatefulSetReplicasMismatch" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeStatefulSetGenerationMismatch | default false) }} + - alert: KubeStatefulSetGenerationMismatch + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: StatefulSet generation for {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.statefulset {{`}}`}} does not match, this indicates that the StatefulSet has failed but has not been rolled back. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubestatefulsetgenerationmismatch + summary: StatefulSet generation mismatch due to possible roll-back + expr: |- + kube_statefulset_status_observed_generation{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + kube_statefulset_metadata_generation{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + for: {{ dig "KubeStatefulSetGenerationMismatch" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeStatefulSetGenerationMismatch" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeStatefulSetUpdateNotRolledOut | default false) }} + - alert: KubeStatefulSetUpdateNotRolledOut + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: StatefulSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.statefulset {{`}}`}} update has not been rolled out. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubestatefulsetupdatenotrolledout + summary: StatefulSet update has not been rolled out. + expr: |- + ( + max without (revision) ( + kube_statefulset_status_current_revision{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + unless + kube_statefulset_status_update_revision{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + ) + * + ( + kube_statefulset_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + kube_statefulset_status_replicas_updated{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + ) + ) and ( + changes(kube_statefulset_status_replicas_updated{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[5m]) + == + 0 + ) + for: {{ dig "KubeStatefulSetUpdateNotRolledOut" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeStatefulSetUpdateNotRolledOut" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeDaemonSetRolloutStuck | default false) }} + - alert: KubeDaemonSetRolloutStuck + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: DaemonSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.daemonset {{`}}`}} has not finished or progressed for at least 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedaemonsetrolloutstuck + summary: DaemonSet rollout is stuck. + expr: |- + ( + ( + kube_daemonset_status_current_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + kube_daemonset_status_desired_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + ) or ( + kube_daemonset_status_number_misscheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + 0 + ) or ( + kube_daemonset_status_updated_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + kube_daemonset_status_desired_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + ) or ( + kube_daemonset_status_number_available{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + kube_daemonset_status_desired_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + ) + ) and ( + changes(kube_daemonset_status_updated_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[5m]) + == + 0 + ) + for: {{ dig "KubeDaemonSetRolloutStuck" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeDaemonSetRolloutStuck" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeContainerWaiting | default false) }} + - alert: KubeContainerWaiting + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: pod/{{`{{`}} $labels.pod {{`}}`}} in namespace {{`{{`}} $labels.namespace {{`}}`}} on container {{`{{`}} $labels.container{{`}}`}} has been in waiting state for longer than 1 hour. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubecontainerwaiting + summary: Pod container waiting longer than 1 hour + expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, pod, container, cluster) (kube_pod_container_status_waiting_reason{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}) > 0 + for: {{ dig "KubeContainerWaiting" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeContainerWaiting" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeDaemonSetNotScheduled | default false) }} + - alert: KubeDaemonSetNotScheduled + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: '{{`{{`}} $value {{`}}`}} Pods of DaemonSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.daemonset {{`}}`}} are not scheduled.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedaemonsetnotscheduled + summary: DaemonSet pods are not scheduled. + expr: |- + kube_daemonset_status_desired_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + - + kube_daemonset_status_current_number_scheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} > 0 + for: {{ dig "KubeDaemonSetNotScheduled" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeDaemonSetNotScheduled" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeDaemonSetMisScheduled | default false) }} + - alert: KubeDaemonSetMisScheduled + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: '{{`{{`}} $value {{`}}`}} Pods of DaemonSet {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.daemonset {{`}}`}} are running where they are not supposed to run.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubedaemonsetmisscheduled + summary: DaemonSet pods are misscheduled. + expr: kube_daemonset_status_number_misscheduled{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} > 0 + for: {{ dig "KubeDaemonSetMisScheduled" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeDaemonSetMisScheduled" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeJobNotCompleted | default false) }} + - alert: KubeJobNotCompleted + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: Job {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.job_name {{`}}`}} is taking more than {{`{{`}} "43200" | humanizeDuration {{`}}`}} to complete. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubejobnotcompleted + summary: Job did not complete in time + expr: |- + time() - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}namespace, job_name, cluster) (kube_job_status_start_time{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + and + kube_job_status_active{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} > 0) > 43200 + labels: + severity: {{ dig "KubeJobNotCompleted" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeJobFailed | default false) }} + - alert: KubeJobFailed + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: Job {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.job_name {{`}}`}} failed to complete. Removing failed job after investigation should clear this alert. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubejobfailed + summary: Job failed to complete. + expr: kube_job_failed{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} > 0 + for: {{ dig "KubeJobFailed" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeJobFailed" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeHpaReplicasMismatch | default false) }} + - alert: KubeHpaReplicasMismatch + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: HPA {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.horizontalpodautoscaler {{`}}`}} has not matched the desired number of replicas for longer than 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubehpareplicasmismatch + summary: HPA has not matched desired number of replicas. + expr: |- + (kube_horizontalpodautoscaler_status_desired_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + != + kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}) + and + (kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + > + kube_horizontalpodautoscaler_spec_min_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}) + and + (kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + < + kube_horizontalpodautoscaler_spec_max_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}) + and + changes(kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"}[15m]) == 0 + for: {{ dig "KubeHpaReplicasMismatch" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeHpaReplicasMismatch" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeHpaMaxedOut | default false) }} + - alert: KubeHpaMaxedOut + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesApps | indent 8 }} +{{- end }} + description: HPA {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.horizontalpodautoscaler {{`}}`}} has been running at max replicas for longer than 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubehpamaxedout + summary: HPA is running at max replicas + expr: |- + kube_horizontalpodautoscaler_status_current_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + == + kube_horizontalpodautoscaler_spec_max_replicas{job="{{ $kubeStateMetricsJob }}", namespace=~"{{ $targetNamespace }}"} + for: {{ dig "KubeHpaMaxedOut" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeHpaMaxedOut" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesApps }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-resources.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-resources.yaml new file mode 100644 index 0000000000..9111285250 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-resources.yaml @@ -0,0 +1,282 @@ +{{- /* +Generated from 'kubernetes-resources' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesResources }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-resources" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-resources + rules: +{{- if not (.Values.defaultRules.disabled.KubeCPUOvercommit | default false) }} + - alert: KubeCPUOvercommit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} +{{- end }} + description: Cluster {{`{{`}} $labels.cluster {{`}}`}} has overcommitted CPU resource requests for Pods by {{`{{`}} $value {{`}}`}} CPU shares and cannot tolerate node failure. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubecpuovercommit + summary: Cluster has overcommitted CPU resource requests. + expr: |- + sum(namespace_cpu:kube_pod_container_resource_requests:sum{job="{{ $kubeStateMetricsJob }}",}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - (sum(kube_node_status_allocatable{job="{{ $kubeStateMetricsJob }}",resource="cpu"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - max(kube_node_status_allocatable{job="{{ $kubeStateMetricsJob }}",resource="cpu"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) > 0 + and + (sum(kube_node_status_allocatable{job="{{ $kubeStateMetricsJob }}",resource="cpu"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - max(kube_node_status_allocatable{job="{{ $kubeStateMetricsJob }}",resource="cpu"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) > 0 + for: {{ dig "KubeCPUOvercommit" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeCPUOvercommit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeMemoryOvercommit | default false) }} + - alert: KubeMemoryOvercommit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} +{{- end }} + description: Cluster {{`{{`}} $labels.cluster {{`}}`}} has overcommitted memory resource requests for Pods by {{`{{`}} $value | humanize {{`}}`}} bytes and cannot tolerate node failure. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubememoryovercommit + summary: Cluster has overcommitted memory resource requests. + expr: |- + sum(namespace_memory:kube_pod_container_resource_requests:sum{}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - (sum(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - max(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) > 0 + and + (sum(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) - max(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster)) > 0 + for: {{ dig "KubeMemoryOvercommit" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeMemoryOvercommit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeCPUQuotaOvercommit | default false) }} + - alert: KubeCPUQuotaOvercommit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} +{{- end }} + description: Cluster {{`{{`}} $labels.cluster {{`}}`}} has overcommitted CPU resource requests for Namespaces. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubecpuquotaovercommit + summary: Cluster has overcommitted CPU resource requests. + expr: |- + sum(min without(resource) (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard", resource=~"(cpu|requests.cpu)"})) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) + / + sum(kube_node_status_allocatable{resource="cpu", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) + > 1.5 + for: {{ dig "KubeCPUQuotaOvercommit" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeCPUQuotaOvercommit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeMemoryQuotaOvercommit | default false) }} + - alert: KubeMemoryQuotaOvercommit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} +{{- end }} + description: Cluster {{`{{`}} $labels.cluster {{`}}`}} has overcommitted memory resource requests for Namespaces. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubememoryquotaovercommit + summary: Cluster has overcommitted memory resource requests. + expr: |- + sum(min without(resource) (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard", resource=~"(memory|requests.memory)"})) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) + / + sum(kube_node_status_allocatable{resource="memory", job="{{ $kubeStateMetricsJob }}"}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) + > 1.5 + for: {{ dig "KubeMemoryQuotaOvercommit" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeMemoryQuotaOvercommit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeQuotaAlmostFull | default false) }} + - alert: KubeQuotaAlmostFull + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} +{{- end }} + description: Namespace {{`{{`}} $labels.namespace {{`}}`}} is using {{`{{`}} $value | humanizePercentage {{`}}`}} of its {{`{{`}} $labels.resource {{`}}`}} quota. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubequotaalmostfull + summary: Namespace quota is going to be full. + expr: |- + kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="used"} + / ignoring(instance, job, type) + (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard"} > 0) + > 0.9 < 1 + for: {{ dig "KubeQuotaAlmostFull" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeQuotaAlmostFull" "severity" "info" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeQuotaFullyUsed | default false) }} + - alert: KubeQuotaFullyUsed + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} +{{- end }} + description: Namespace {{`{{`}} $labels.namespace {{`}}`}} is using {{`{{`}} $value | humanizePercentage {{`}}`}} of its {{`{{`}} $labels.resource {{`}}`}} quota. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubequotafullyused + summary: Namespace quota is fully used. + expr: |- + kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="used"} + / ignoring(instance, job, type) + (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard"} > 0) + == 1 + for: {{ dig "KubeQuotaFullyUsed" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeQuotaFullyUsed" "severity" "info" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeQuotaExceeded | default false) }} + - alert: KubeQuotaExceeded + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} +{{- end }} + description: Namespace {{`{{`}} $labels.namespace {{`}}`}} is using {{`{{`}} $value | humanizePercentage {{`}}`}} of its {{`{{`}} $labels.resource {{`}}`}} quota. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubequotaexceeded + summary: Namespace quota has exceeded the limits. + expr: |- + kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="used"} + / ignoring(instance, job, type) + (kube_resourcequota{job="{{ $kubeStateMetricsJob }}", type="hard"} > 0) + > 1 + for: {{ dig "KubeQuotaExceeded" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeQuotaExceeded" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.CPUThrottlingHigh | default false) }} + - alert: CPUThrottlingHigh + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesResources | indent 8 }} +{{- end }} + description: '{{`{{`}} $value | humanizePercentage {{`}}`}} throttling of CPU in namespace {{`{{`}} $labels.namespace {{`}}`}} for container {{`{{`}} $labels.container {{`}}`}} in pod {{`{{`}} $labels.pod {{`}}`}}.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/cputhrottlinghigh + summary: Processes experience elevated CPU throttling. + expr: |- + sum(increase(container_cpu_cfs_throttled_periods_total{container!="", }[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, container, pod, namespace) + / + sum(increase(container_cpu_cfs_periods_total{}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, container, pod, namespace) + > ( 25 / 100 ) + for: {{ dig "CPUThrottlingHigh" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "CPUThrottlingHigh" "severity" "info" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesResources }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-storage.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-storage.yaml new file mode 100644 index 0000000000..809e544885 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-storage.yaml @@ -0,0 +1,216 @@ +{{- /* +Generated from 'kubernetes-storage' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesStorage }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +{{- $targetNamespace := .Values.defaultRules.appNamespacesTarget }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-storage" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-storage + rules: +{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeFillingUp | default false) }} + - alert: KubePersistentVolumeFillingUp + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} +{{- end }} + description: The PersistentVolume claimed by {{`{{`}} $labels.persistentvolumeclaim {{`}}`}} in Namespace {{`{{`}} $labels.namespace {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} is only {{`{{`}} $value | humanizePercentage {{`}}`}} free. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumefillingup + summary: PersistentVolume is filling up. + expr: |- + kubelet_volume_stats_available_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} + / + kubelet_volume_stats_capacity_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} + < 0.03 + and + kubelet_volume_stats_used_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} > 0 + unless on(namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 + unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 + for: {{ dig "KubePersistentVolumeFillingUp" "for" "1m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubePersistentVolumeFillingUp" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeFillingUp | default false) }} + - alert: KubePersistentVolumeFillingUp + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} +{{- end }} + description: Based on recent sampling, the PersistentVolume claimed by {{`{{`}} $labels.persistentvolumeclaim {{`}}`}} in Namespace {{`{{`}} $labels.namespace {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} is expected to fill up within four days. Currently {{`{{`}} $value | humanizePercentage {{`}}`}} is available. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumefillingup + summary: PersistentVolume is filling up. + expr: |- + ( + kubelet_volume_stats_available_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} + / + kubelet_volume_stats_capacity_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} + ) < 0.15 + and + kubelet_volume_stats_used_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} > 0 + and + predict_linear(kubelet_volume_stats_available_bytes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"}[6h], 4 * 24 * 3600) < 0 + unless on(namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 + unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 + for: {{ dig "KubePersistentVolumeFillingUp" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubePersistentVolumeFillingUp" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeInodesFillingUp | default false) }} + - alert: KubePersistentVolumeInodesFillingUp + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} +{{- end }} + description: The PersistentVolume claimed by {{`{{`}} $labels.persistentvolumeclaim {{`}}`}} in Namespace {{`{{`}} $labels.namespace {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} only has {{`{{`}} $value | humanizePercentage {{`}}`}} free inodes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumeinodesfillingup + summary: PersistentVolumeInodes are filling up. + expr: |- + ( + kubelet_volume_stats_inodes_free{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} + / + kubelet_volume_stats_inodes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} + ) < 0.03 + and + kubelet_volume_stats_inodes_used{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} > 0 + unless on(namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 + unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 + for: {{ dig "KubePersistentVolumeInodesFillingUp" "for" "1m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubePersistentVolumeInodesFillingUp" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeInodesFillingUp | default false) }} + - alert: KubePersistentVolumeInodesFillingUp + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} +{{- end }} + description: Based on recent sampling, the PersistentVolume claimed by {{`{{`}} $labels.persistentvolumeclaim {{`}}`}} in Namespace {{`{{`}} $labels.namespace {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} is expected to run out of inodes within four days. Currently {{`{{`}} $value | humanizePercentage {{`}}`}} of its inodes are free. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumeinodesfillingup + summary: PersistentVolumeInodes are filling up. + expr: |- + ( + kubelet_volume_stats_inodes_free{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} + / + kubelet_volume_stats_inodes{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} + ) < 0.15 + and + kubelet_volume_stats_inodes_used{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"} > 0 + and + predict_linear(kubelet_volume_stats_inodes_free{job="{{ include "exporter.kubelet.jobName" . }}", namespace=~"{{ $targetNamespace }}", metrics_path="/metrics"}[6h], 4 * 24 * 3600) < 0 + unless on(namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 + unless on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, persistentvolumeclaim) + kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 + for: {{ dig "KubePersistentVolumeInodesFillingUp" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubePersistentVolumeInodesFillingUp" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubePersistentVolumeErrors | default false) }} + - alert: KubePersistentVolumeErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesStorage | indent 8 }} +{{- end }} + description: The persistent volume {{`{{`}} $labels.persistentvolume {{`}}`}} {{`{{`}} with $labels.cluster -{{`}}`}} on Cluster {{`{{`}} . {{`}}`}} {{`{{`}}- end {{`}}`}} has status {{`{{`}} $labels.phase {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubepersistentvolumeerrors + summary: PersistentVolume is having issues with provisioning. + expr: kube_persistentvolume_status_phase{phase=~"Failed|Pending",job="{{ $kubeStateMetricsJob }}"} > 0 + for: {{ dig "KubePersistentVolumeErrors" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubePersistentVolumeErrors" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesStorage }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml new file mode 100644 index 0000000000..6dd61b5f5c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-apiserver.yaml @@ -0,0 +1,193 @@ +{{- /* +Generated from 'kubernetes-system-apiserver' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesSystem }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-apiserver" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-system-apiserver + rules: +{{- if not (.Values.defaultRules.disabled.KubeClientCertificateExpiration | default false) }} + - alert: KubeClientCertificateExpiration + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: A client certificate used to authenticate to kubernetes apiserver is expiring in less than 7.0 days. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeclientcertificateexpiration + summary: Client certificate is about to expire. + expr: apiserver_client_certificate_expiration_seconds_count{job="apiserver"} > 0 and on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}job) histogram_quantile(0.01, sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}job, le) (rate(apiserver_client_certificate_expiration_seconds_bucket{job="apiserver"}[5m]))) < 604800 + for: {{ dig "KubeClientCertificateExpiration" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeClientCertificateExpiration" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeClientCertificateExpiration | default false) }} + - alert: KubeClientCertificateExpiration + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: A client certificate used to authenticate to kubernetes apiserver is expiring in less than 24.0 hours. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeclientcertificateexpiration + summary: Client certificate is about to expire. + expr: apiserver_client_certificate_expiration_seconds_count{job="apiserver"} > 0 and on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}job) histogram_quantile(0.01, sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}job, le) (rate(apiserver_client_certificate_expiration_seconds_bucket{job="apiserver"}[5m]))) < 86400 + for: {{ dig "KubeClientCertificateExpiration" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeClientCertificateExpiration" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeAggregatedAPIErrors | default false) }} + - alert: KubeAggregatedAPIErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Kubernetes aggregated API {{`{{`}} $labels.name {{`}}`}}/{{`{{`}} $labels.namespace {{`}}`}} has reported errors. It has appeared unavailable {{`{{`}} $value | humanize {{`}}`}} times averaged over the past 10m. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeaggregatedapierrors + summary: Kubernetes aggregated API has reported errors. + expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}name, namespace, cluster)(increase(aggregator_unavailable_apiservice_total{job="apiserver"}[10m])) > 4 + labels: + severity: {{ dig "KubeAggregatedAPIErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeAggregatedAPIDown | default false) }} + - alert: KubeAggregatedAPIDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Kubernetes aggregated API {{`{{`}} $labels.name {{`}}`}}/{{`{{`}} $labels.namespace {{`}}`}} has been only {{`{{`}} $value | humanize {{`}}`}}% available over the last 10m. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeaggregatedapidown + summary: Kubernetes aggregated API is down. + expr: (1 - max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}name, namespace, cluster)(avg_over_time(aggregator_unavailable_apiservice{job="apiserver"}[10m]))) * 100 < 85 + for: {{ dig "KubeAggregatedAPIDown" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeAggregatedAPIDown" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.kubeApiServer.enabled }} +{{- if not (.Values.defaultRules.disabled.KubeAPIDown | default false) }} + - alert: KubeAPIDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: KubeAPI has disappeared from Prometheus target discovery. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapidown + summary: Target disappeared from Prometheus target discovery. + expr: absent(up{job="apiserver"} == 1) + for: {{ dig "KubeAPIDown" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeAPIDown" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeAPITerminatedRequests | default false) }} + - alert: KubeAPITerminatedRequests + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: The kubernetes apiserver has terminated {{`{{`}} $value | humanizePercentage {{`}}`}} of its incoming requests. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeapiterminatedrequests + summary: The kubernetes apiserver has terminated {{`{{`}} $value | humanizePercentage {{`}}`}} of its incoming requests. + expr: sum(rate(apiserver_request_terminations_total{job="apiserver"}[10m])) / ( sum(rate(apiserver_request_total{job="apiserver"}[10m])) + sum(rate(apiserver_request_terminations_total{job="apiserver"}[10m])) ) > 0.20 + for: {{ dig "KubeAPITerminatedRequests" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeAPITerminatedRequests" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml new file mode 100644 index 0000000000..43b324596e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-controller-manager.yaml @@ -0,0 +1,57 @@ +{{- /* +Generated from 'kubernetes-system-controller-manager' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubeControllerManager }} +{{- if (include "exporter.kubeControllerManager.enabled" .)}} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-controller-manager" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-system-controller-manager + rules: +{{- if .Values.kubeControllerManager.enabled }} +{{- if not (.Values.defaultRules.disabled.KubeControllerManagerDown | default false) }} + - alert: KubeControllerManagerDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeControllerManager }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeControllerManager | indent 8 }} +{{- end }} + description: KubeControllerManager has disappeared from Prometheus target discovery. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubecontrollermanagerdown + summary: Target disappeared from Prometheus target discovery. + expr: absent(up{job="{{ include "exporter.kubeControllerManager.jobName" . }}"} == 1) + for: 15m + labels: + severity: {{ dig "KubeControllerManagerDown" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeControllerManager }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeControllerManager }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} + diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml new file mode 100644 index 0000000000..2000acece2 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kube-proxy.yaml @@ -0,0 +1,52 @@ +{{- /* +Generated from 'kubernetes-system-kube-proxy' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeProxy.enabled .Values.defaultRules.rules.kubeProxy }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-kube-proxy" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-system-kube-proxy + rules: +{{- if not (.Values.defaultRules.disabled.KubeProxyDown | default false) }} + - alert: KubeProxyDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeProxy }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeProxy | indent 8 }} +{{- end }} + description: KubeProxy has disappeared from Prometheus target discovery. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeproxydown + summary: Target disappeared from Prometheus target discovery. + expr: absent(up{job="{{ include "exporter.kubeProxy.jobName" . }}"} == 1) + for: 15m + labels: + severity: {{ dig "KubeProxyDown" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeProxy }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeProxy }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml new file mode 100644 index 0000000000..d2cf87422d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-kubelet.yaml @@ -0,0 +1,379 @@ +{{- /* +Generated from 'kubernetes-system-kubelet' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesSystem }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-kubelet" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-system-kubelet + rules: +{{- if not (.Values.defaultRules.disabled.KubeNodeNotReady | default false) }} + - alert: KubeNodeNotReady + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: '{{`{{`}} $labels.node {{`}}`}} has been unready for more than 15 minutes.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubenodenotready + summary: Node is not ready. + expr: kube_node_status_condition{job="{{ $kubeStateMetricsJob }}",condition="Ready",status="true"} == 0 + for: {{ dig "KubeNodeNotReady" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeNodeNotReady" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeNodeUnreachable | default false) }} + - alert: KubeNodeUnreachable + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: '{{`{{`}} $labels.node {{`}}`}} is unreachable and some workloads may be rescheduled.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubenodeunreachable + summary: Node is unreachable. + expr: (kube_node_spec_taint{job="{{ $kubeStateMetricsJob }}",key="node.kubernetes.io/unreachable",effect="NoSchedule"} unless ignoring(key,value) kube_node_spec_taint{job="{{ $kubeStateMetricsJob }}",key=~"ToBeDeletedByClusterAutoscaler|cloud.google.com/impending-node-termination|aws-node-termination-handler/spot-itn"}) == 1 + for: {{ dig "KubeNodeUnreachable" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeNodeUnreachable" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletTooManyPods | default false) }} + - alert: KubeletTooManyPods + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Kubelet '{{`{{`}} $labels.node {{`}}`}}' is running at {{`{{`}} $value | humanizePercentage {{`}}`}} of its Pod capacity. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubelettoomanypods + summary: Kubelet is running at capacity. + expr: |- + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) ( + (kube_pod_status_phase{job="{{ $kubeStateMetricsJob }}",phase="Running"} == 1) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance,pod,namespace,cluster) group_left(node) topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}instance,pod,namespace,cluster) (1, kube_pod_info{job="{{ $kubeStateMetricsJob }}"}) + ) + / + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) ( + kube_node_status_capacity{job="{{ $kubeStateMetricsJob }}",resource="pods"} != 1 + ) > 0.95 + for: {{ dig "KubeletTooManyPods" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeletTooManyPods" "severity" "info" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeNodeReadinessFlapping | default false) }} + - alert: KubeNodeReadinessFlapping + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: The readiness status of node {{`{{`}} $labels.node {{`}}`}} has changed {{`{{`}} $value {{`}}`}} times in the last 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubenodereadinessflapping + summary: Node readiness status is flapping. + expr: sum(changes(kube_node_status_condition{job="{{ $kubeStateMetricsJob }}",status="true",condition="Ready"}[15m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) > 2 + for: {{ dig "KubeNodeReadinessFlapping" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeNodeReadinessFlapping" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletPlegDurationHigh | default false) }} + - alert: KubeletPlegDurationHigh + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: The Kubelet Pod Lifecycle Event Generator has a 99th percentile duration of {{`{{`}} $value {{`}}`}} seconds on node {{`{{`}} $labels.node {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletplegdurationhigh + summary: Kubelet Pod Lifecycle Event Generator is taking too long to relist. + expr: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile{quantile="0.99"} >= 10 + for: {{ dig "KubeletPlegDurationHigh" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeletPlegDurationHigh" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletPodStartUpLatencyHigh | default false) }} + - alert: KubeletPodStartUpLatencyHigh + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Kubelet Pod startup 99th percentile latency is {{`{{`}} $value {{`}}`}} seconds on node {{`{{`}} $labels.node {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletpodstartuplatencyhigh + summary: Kubelet Pod startup latency is too high. + expr: histogram_quantile(0.99, sum(rate(kubelet_pod_worker_duration_seconds_bucket{job="{{ include "exporter.kubelet.jobName" . }}", metrics_path="/metrics"}[5m])) by (cluster, instance, le)) * on(cluster, instance) group_left(node) kubelet_node_name{job="{{ include "exporter.kubelet.jobName" . }}", metrics_path="/metrics"} > 60 + for: 15m + labels: + severity: {{ dig "KubeletPodStartUpLatencyHigh" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletClientCertificateExpiration | default false) }} + - alert: KubeletClientCertificateExpiration + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Client certificate for Kubelet on node {{`{{`}} $labels.node {{`}}`}} expires in {{`{{`}} $value | humanizeDuration {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletclientcertificateexpiration + summary: Kubelet client certificate is about to expire. + expr: kubelet_certificate_manager_client_ttl_seconds < 604800 + labels: + severity: {{ dig "KubeletClientCertificateExpiration" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletClientCertificateExpiration | default false) }} + - alert: KubeletClientCertificateExpiration + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Client certificate for Kubelet on node {{`{{`}} $labels.node {{`}}`}} expires in {{`{{`}} $value | humanizeDuration {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletclientcertificateexpiration + summary: Kubelet client certificate is about to expire. + expr: kubelet_certificate_manager_client_ttl_seconds < 86400 + labels: + severity: {{ dig "KubeletClientCertificateExpiration" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletServerCertificateExpiration | default false) }} + - alert: KubeletServerCertificateExpiration + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Server certificate for Kubelet on node {{`{{`}} $labels.node {{`}}`}} expires in {{`{{`}} $value | humanizeDuration {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletservercertificateexpiration + summary: Kubelet server certificate is about to expire. + expr: kubelet_certificate_manager_server_ttl_seconds < 604800 + labels: + severity: {{ dig "KubeletServerCertificateExpiration" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletServerCertificateExpiration | default false) }} + - alert: KubeletServerCertificateExpiration + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Server certificate for Kubelet on node {{`{{`}} $labels.node {{`}}`}} expires in {{`{{`}} $value | humanizeDuration {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletservercertificateexpiration + summary: Kubelet server certificate is about to expire. + expr: kubelet_certificate_manager_server_ttl_seconds < 86400 + labels: + severity: {{ dig "KubeletServerCertificateExpiration" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletClientCertificateRenewalErrors | default false) }} + - alert: KubeletClientCertificateRenewalErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Kubelet on node {{`{{`}} $labels.node {{`}}`}} has failed to renew its client certificate ({{`{{`}} $value | humanize {{`}}`}} errors in the last 5 minutes). + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletclientcertificaterenewalerrors + summary: Kubelet has failed to renew its client certificate. + expr: increase(kubelet_certificate_manager_client_expiration_renew_errors[5m]) > 0 + for: {{ dig "KubeletClientCertificateRenewalErrors" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeletClientCertificateRenewalErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeletServerCertificateRenewalErrors | default false) }} + - alert: KubeletServerCertificateRenewalErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Kubelet on node {{`{{`}} $labels.node {{`}}`}} has failed to renew its server certificate ({{`{{`}} $value | humanize {{`}}`}} errors in the last 5 minutes). + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletservercertificaterenewalerrors + summary: Kubelet has failed to renew its server certificate. + expr: increase(kubelet_server_expiration_renew_errors[5m]) > 0 + for: {{ dig "KubeletServerCertificateRenewalErrors" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeletServerCertificateRenewalErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if (include "exporter.kubelet.enabled" .)}} +{{- if not (.Values.defaultRules.disabled.KubeletDown | default false) }} + - alert: KubeletDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Kubelet has disappeared from Prometheus target discovery. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeletdown + summary: Target disappeared from Prometheus target discovery. + expr: absent(up{job="{{ include "exporter.kubelet.jobName" . }}", metrics_path="/metrics"} == 1) + for: 15m + labels: + severity: {{ dig "KubeletDown" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml new file mode 100644 index 0000000000..d32f15139d --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system-scheduler.yaml @@ -0,0 +1,54 @@ +{{- /* +Generated from 'kubernetes-system-scheduler' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.kubeScheduler.enabled .Values.defaultRules.rules.kubeSchedulerAlerting }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system-scheduler" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-system-scheduler + rules: +{{- if .Values.kubeScheduler.enabled }} +{{- if not (.Values.defaultRules.disabled.KubeSchedulerDown | default false) }} + - alert: KubeSchedulerDown + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubeSchedulerAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubeSchedulerAlerting | indent 8 }} +{{- end }} + description: KubeScheduler has disappeared from Prometheus target discovery. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeschedulerdown + summary: Target disappeared from Prometheus target discovery. + expr: absent(up{job="{{ include "exporter.kubeScheduler.jobName" . }}"} == 1) + for: 15m + labels: + severity: {{ dig "KubeSchedulerDown" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubeSchedulerAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system.yaml new file mode 100644 index 0000000000..929a6f43bd --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/kubernetes-system.yaml @@ -0,0 +1,87 @@ +{{- /* +Generated from 'kubernetes-system' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.kubernetesSystem }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "kubernetes-system" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: kubernetes-system + rules: +{{- if not (.Values.defaultRules.disabled.KubeVersionMismatch | default false) }} + - alert: KubeVersionMismatch + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: There are {{`{{`}} $value {{`}}`}} different semantic versions of Kubernetes components running. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeversionmismatch + summary: Different semantic versions of Kubernetes components running. + expr: count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}git_version, cluster) (label_replace(kubernetes_build_info{job!~"kube-dns|coredns"},"git_version","$1","git_version","(v[0-9]*.[0-9]*).*"))) > 1 + for: {{ dig "KubeVersionMismatch" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeVersionMismatch" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.KubeClientErrors | default false) }} + - alert: KubeClientErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.kubernetesSystem | indent 8 }} +{{- end }} + description: Kubernetes API server client '{{`{{`}} $labels.job {{`}}`}}/{{`{{`}} $labels.instance {{`}}`}}' is experiencing {{`{{`}} $value | humanizePercentage {{`}}`}} errors.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/kubernetes/kubeclienterrors + summary: Kubernetes API server client is experiencing errors. + expr: |- + (sum(rate(rest_client_requests_total{job="apiserver",code=~"5.."}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, job, namespace) + / + sum(rate(rest_client_requests_total{job="apiserver"}[5m])) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, job, namespace)) + > 0.01 + for: {{ dig "KubeClientErrors" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "KubeClientErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.kubernetesSystem }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-exporter.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-exporter.rules.yaml new file mode 100644 index 0000000000..aeaa80231c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-exporter.rules.yaml @@ -0,0 +1,188 @@ +{{- /* +Generated from 'node-exporter.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.nodeExporterRecording }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "node-exporter.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: node-exporter.rules + rules: + - expr: |- + count without (cpu, mode) ( + node_cpu_seconds_total{job="node-exporter",mode="idle"} + ) + record: instance:node_num_cpu:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + 1 - avg without (cpu) ( + sum without (mode) (rate(node_cpu_seconds_total{job="node-exporter", mode=~"idle|iowait|steal"}[5m])) + ) + record: instance:node_cpu_utilisation:rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + ( + node_load1{job="node-exporter"} + / + instance:node_num_cpu:sum{job="node-exporter"} + ) + record: instance:node_load1_per_cpu:ratio + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + 1 - ( + ( + node_memory_MemAvailable_bytes{job="node-exporter"} + or + ( + node_memory_Buffers_bytes{job="node-exporter"} + + + node_memory_Cached_bytes{job="node-exporter"} + + + node_memory_MemFree_bytes{job="node-exporter"} + + + node_memory_Slab_bytes{job="node-exporter"} + ) + ) + / + node_memory_MemTotal_bytes{job="node-exporter"} + ) + record: instance:node_memory_utilisation:ratio + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: rate(node_vmstat_pgmajfault{job="node-exporter"}[5m]) + record: instance:node_vmstat_pgmajfault:rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: rate(node_disk_io_time_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) + record: instance_device:node_disk_io_time_seconds:rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: rate(node_disk_io_time_weighted_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) + record: instance_device:node_disk_io_time_weighted_seconds:rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum without (device) ( + rate(node_network_receive_bytes_total{job="node-exporter", device!="lo"}[5m]) + ) + record: instance:node_network_receive_bytes_excluding_lo:rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum without (device) ( + rate(node_network_transmit_bytes_total{job="node-exporter", device!="lo"}[5m]) + ) + record: instance:node_network_transmit_bytes_excluding_lo:rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum without (device) ( + rate(node_network_receive_drop_total{job="node-exporter", device!="lo"}[5m]) + ) + record: instance:node_network_receive_drop_excluding_lo:rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum without (device) ( + rate(node_network_transmit_drop_total{job="node-exporter", device!="lo"}[5m]) + ) + record: instance:node_network_transmit_drop_excluding_lo:rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterRecording }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-exporter.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-exporter.yaml new file mode 100644 index 0000000000..80bfd9bf36 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-exporter.yaml @@ -0,0 +1,801 @@ +{{- /* +Generated from 'node-exporter' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.nodeExporterAlerting }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "node-exporter" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: node-exporter + rules: +{{- if not (.Values.defaultRules.disabled.NodeFilesystemSpaceFillingUp | default false) }} + - alert: NodeFilesystemSpaceFillingUp + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available space left and is filling up. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemspacefillingup + summary: Filesystem is predicted to run out of space within the next 24 hours. + expr: |- + ( + node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 15 + and + predict_linear(node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""}[6h], 24*60*60) < 0 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: {{ dig "NodeFilesystemSpaceFillingUp" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFilesystemSpaceFillingUp" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFilesystemSpaceFillingUp | default false) }} + - alert: NodeFilesystemSpaceFillingUp + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available space left and is filling up fast. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemspacefillingup + summary: Filesystem is predicted to run out of space within the next 4 hours. + expr: |- + ( + node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 10 + and + predict_linear(node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""}[6h], 4*60*60) < 0 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: {{ dig "NodeFilesystemSpaceFillingUp" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFilesystemSpaceFillingUp" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFilesystemAlmostOutOfSpace | default false) }} + - alert: NodeFilesystemAlmostOutOfSpace + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available space left. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemalmostoutofspace + summary: Filesystem has less than 5% space left. + expr: |- + ( + node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 5 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: {{ dig "NodeFilesystemAlmostOutOfSpace" "for" "30m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFilesystemAlmostOutOfSpace" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFilesystemAlmostOutOfSpace | default false) }} + - alert: NodeFilesystemAlmostOutOfSpace + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available space left. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemalmostoutofspace + summary: Filesystem has less than 3% space left. + expr: |- + ( + node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 3 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: {{ dig "NodeFilesystemAlmostOutOfSpace" "for" "30m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFilesystemAlmostOutOfSpace" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFilesystemFilesFillingUp | default false) }} + - alert: NodeFilesystemFilesFillingUp + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available inodes left and is filling up. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemfilesfillingup + summary: Filesystem is predicted to run out of inodes within the next 24 hours. + expr: |- + ( + node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 40 + and + predict_linear(node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""}[6h], 24*60*60) < 0 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: {{ dig "NodeFilesystemFilesFillingUp" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFilesystemFilesFillingUp" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFilesystemFilesFillingUp | default false) }} + - alert: NodeFilesystemFilesFillingUp + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available inodes left and is filling up fast. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemfilesfillingup + summary: Filesystem is predicted to run out of inodes within the next 4 hours. + expr: |- + ( + node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 20 + and + predict_linear(node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""}[6h], 4*60*60) < 0 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: {{ dig "NodeFilesystemFilesFillingUp" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFilesystemFilesFillingUp" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFilesystemAlmostOutOfFiles | default false) }} + - alert: NodeFilesystemAlmostOutOfFiles + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available inodes left. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemalmostoutoffiles + summary: Filesystem has less than 5% inodes left. + expr: |- + ( + node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 5 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: {{ dig "NodeFilesystemAlmostOutOfFiles" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFilesystemAlmostOutOfFiles" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFilesystemAlmostOutOfFiles | default false) }} + - alert: NodeFilesystemAlmostOutOfFiles + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Filesystem on {{`{{`}} $labels.device {{`}}`}}, mounted on {{`{{`}} $labels.mountpoint {{`}}`}}, at {{`{{`}} $labels.instance {{`}}`}} has only {{`{{`}} printf "%.2f" $value {{`}}`}}% available inodes left. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefilesystemalmostoutoffiles + summary: Filesystem has less than 3% inodes left. + expr: |- + ( + node_filesystem_files_free{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_files{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 3 + and + node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0 + ) + for: {{ dig "NodeFilesystemAlmostOutOfFiles" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFilesystemAlmostOutOfFiles" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeNetworkReceiveErrs | default false) }} + - alert: NodeNetworkReceiveErrs + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: '{{`{{`}} $labels.instance {{`}}`}} interface {{`{{`}} $labels.device {{`}}`}} has encountered {{`{{`}} printf "%.0f" $value {{`}}`}} receive errors in the last two minutes.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodenetworkreceiveerrs + summary: Network interface is reporting many receive errors. + expr: rate(node_network_receive_errs_total{job="node-exporter"}[2m]) / rate(node_network_receive_packets_total{job="node-exporter"}[2m]) > 0.01 + for: {{ dig "NodeNetworkReceiveErrs" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeNetworkReceiveErrs" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeNetworkTransmitErrs | default false) }} + - alert: NodeNetworkTransmitErrs + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: '{{`{{`}} $labels.instance {{`}}`}} interface {{`{{`}} $labels.device {{`}}`}} has encountered {{`{{`}} printf "%.0f" $value {{`}}`}} transmit errors in the last two minutes.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodenetworktransmiterrs + summary: Network interface is reporting many transmit errors. + expr: rate(node_network_transmit_errs_total{job="node-exporter"}[2m]) / rate(node_network_transmit_packets_total{job="node-exporter"}[2m]) > 0.01 + for: {{ dig "NodeNetworkTransmitErrs" "for" "1h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeNetworkTransmitErrs" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeHighNumberConntrackEntriesUsed | default false) }} + - alert: NodeHighNumberConntrackEntriesUsed + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of conntrack entries are used.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodehighnumberconntrackentriesused + summary: Number of conntrack are getting close to the limit. + expr: (node_nf_conntrack_entries{job="node-exporter"} / node_nf_conntrack_entries_limit) > 0.75 + labels: + severity: {{ dig "NodeHighNumberConntrackEntriesUsed" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeTextFileCollectorScrapeError | default false) }} + - alert: NodeTextFileCollectorScrapeError + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Node Exporter text file collector on {{`{{`}} $labels.instance {{`}}`}} failed to scrape. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodetextfilecollectorscrapeerror + summary: Node Exporter text file collector failed to scrape. + expr: node_textfile_scrape_error{job="node-exporter"} == 1 + labels: + severity: {{ dig "NodeTextFileCollectorScrapeError" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeClockSkewDetected | default false) }} + - alert: NodeClockSkewDetected + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Clock at {{`{{`}} $labels.instance {{`}}`}} is out of sync by more than 0.05s. Ensure NTP is configured correctly on this host. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodeclockskewdetected + summary: Clock skew detected. + expr: |- + ( + node_timex_offset_seconds{job="node-exporter"} > 0.05 + and + deriv(node_timex_offset_seconds{job="node-exporter"}[5m]) >= 0 + ) + or + ( + node_timex_offset_seconds{job="node-exporter"} < -0.05 + and + deriv(node_timex_offset_seconds{job="node-exporter"}[5m]) <= 0 + ) + for: {{ dig "NodeClockSkewDetected" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeClockSkewDetected" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeClockNotSynchronising | default false) }} + - alert: NodeClockNotSynchronising + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Clock at {{`{{`}} $labels.instance {{`}}`}} is not synchronising. Ensure NTP is configured on this host. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodeclocknotsynchronising + summary: Clock not synchronising. + expr: |- + min_over_time(node_timex_sync_status{job="node-exporter"}[5m]) == 0 + and + node_timex_maxerror_seconds{job="node-exporter"} >= 16 + for: {{ dig "NodeClockNotSynchronising" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeClockNotSynchronising" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeRAIDDegraded | default false) }} + - alert: NodeRAIDDegraded + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: RAID array '{{`{{`}} $labels.device {{`}}`}}' at {{`{{`}} $labels.instance {{`}}`}} is in degraded state due to one or more disks failures. Number of spare drives is insufficient to fix issue automatically. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/noderaiddegraded + summary: RAID Array is degraded. + expr: node_md_disks_required{job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"} - ignoring (state) (node_md_disks{state="active",job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}) > 0 + for: {{ dig "NodeRAIDDegraded" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeRAIDDegraded" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeRAIDDiskFailure | default false) }} + - alert: NodeRAIDDiskFailure + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: At least one device in RAID array at {{`{{`}} $labels.instance {{`}}`}} failed. Array '{{`{{`}} $labels.device {{`}}`}}' needs attention and possibly a disk swap. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/noderaiddiskfailure + summary: Failed device in RAID array. + expr: node_md_disks{state="failed",job="node-exporter",device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"} > 0 + labels: + severity: {{ dig "NodeRAIDDiskFailure" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFileDescriptorLimit | default false) }} + - alert: NodeFileDescriptorLimit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: File descriptors limit at {{`{{`}} $labels.instance {{`}}`}} is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}%. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefiledescriptorlimit + summary: Kernel is predicted to exhaust file descriptors limit soon. + expr: |- + ( + node_filefd_allocated{job="node-exporter"} * 100 / node_filefd_maximum{job="node-exporter"} > 70 + ) + for: {{ dig "NodeFileDescriptorLimit" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFileDescriptorLimit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeFileDescriptorLimit | default false) }} + - alert: NodeFileDescriptorLimit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: File descriptors limit at {{`{{`}} $labels.instance {{`}}`}} is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}%. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodefiledescriptorlimit + summary: Kernel is predicted to exhaust file descriptors limit soon. + expr: |- + ( + node_filefd_allocated{job="node-exporter"} * 100 / node_filefd_maximum{job="node-exporter"} > 90 + ) + for: {{ dig "NodeFileDescriptorLimit" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeFileDescriptorLimit" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeCPUHighUsage | default false) }} + - alert: NodeCPUHighUsage + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: 'CPU usage at {{`{{`}} $labels.instance {{`}}`}} has been above 90% for the last 15 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}%. + + ' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodecpuhighusage + summary: High CPU usage. + expr: sum without(mode) (avg without (cpu) (rate(node_cpu_seconds_total{job="node-exporter", mode!="idle"}[2m]))) * 100 > 90 + for: {{ dig "NodeCPUHighUsage" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeCPUHighUsage" "severity" "info" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeSystemSaturation | default false) }} + - alert: NodeSystemSaturation + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: 'System load per core at {{`{{`}} $labels.instance {{`}}`}} has been above 2 for the last 15 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}. + + This might indicate this instance resources saturation and can cause it becoming unresponsive. + + ' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodesystemsaturation + summary: System saturated, load per core is very high. + expr: |- + node_load1{job="node-exporter"} + / count without (cpu, mode) (node_cpu_seconds_total{job="node-exporter", mode="idle"}) > 2 + for: {{ dig "NodeSystemSaturation" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeSystemSaturation" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeMemoryMajorPagesFaults | default false) }} + - alert: NodeMemoryMajorPagesFaults + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: 'Memory major pages are occurring at very high rate at {{`{{`}} $labels.instance {{`}}`}}, 500 major page faults per second for the last 15 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}. + + Please check that there is enough memory available at this instance. + + ' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodememorymajorpagesfaults + summary: Memory major page faults are occurring at very high rate. + expr: rate(node_vmstat_pgmajfault{job="node-exporter"}[5m]) > 500 + for: {{ dig "NodeMemoryMajorPagesFaults" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeMemoryMajorPagesFaults" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeMemoryHighUtilization | default false) }} + - alert: NodeMemoryHighUtilization + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: 'Memory is filling up at {{`{{`}} $labels.instance {{`}}`}}, has been above 90% for the last 15 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}%. + + ' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodememoryhighutilization + summary: Host is running out of memory. + expr: 100 - (node_memory_MemAvailable_bytes{job="node-exporter"} / node_memory_MemTotal_bytes{job="node-exporter"} * 100) > 90 + for: {{ dig "NodeMemoryHighUtilization" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeMemoryHighUtilization" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeDiskIOSaturation | default false) }} + - alert: NodeDiskIOSaturation + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: 'Disk IO queue (aqu-sq) is high on {{`{{`}} $labels.device {{`}}`}} at {{`{{`}} $labels.instance {{`}}`}}, has been above 10 for the last 30 minutes, is currently at {{`{{`}} printf "%.2f" $value {{`}}`}}. + + This symptom might indicate disk saturation. + + ' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodediskiosaturation + summary: Disk IO queue is high. + expr: rate(node_disk_io_time_weighted_seconds_total{job="node-exporter", device=~"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)"}[5m]) > 10 + for: {{ dig "NodeDiskIOSaturation" "for" "30m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeDiskIOSaturation" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeSystemdServiceFailed | default false) }} + - alert: NodeSystemdServiceFailed + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Systemd service {{`{{`}} $labels.name {{`}}`}} has entered failed state at {{`{{`}} $labels.instance {{`}}`}} + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodesystemdservicefailed + summary: Systemd service has entered failed state. + expr: node_systemd_unit_state{job="node-exporter", state="failed"} == 1 + for: {{ dig "NodeSystemdServiceFailed" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeSystemdServiceFailed" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.NodeBondingDegraded | default false) }} + - alert: NodeBondingDegraded + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.nodeExporterAlerting | indent 8 }} +{{- end }} + description: Bonding interface {{`{{`}} $labels.master {{`}}`}} on {{`{{`}} $labels.instance {{`}}`}} is in degraded state due to one or more slave failures. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/node/nodebondingdegraded + summary: Bonding interface is degraded + expr: (node_bonding_slaves - node_bonding_active) != 0 + for: {{ dig "NodeBondingDegraded" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeBondingDegraded" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.nodeExporterAlerting }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-network.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-network.yaml new file mode 100644 index 0000000000..16690ee313 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node-network.yaml @@ -0,0 +1,55 @@ +{{- /* +Generated from 'node-network' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.network }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "node-network" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: node-network + rules: +{{- if not (.Values.defaultRules.disabled.NodeNetworkInterfaceFlapping | default false) }} + - alert: NodeNetworkInterfaceFlapping + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.network }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.network | indent 8 }} +{{- end }} + description: Network interface "{{`{{`}} $labels.device {{`}}`}}" changing its up status often on node-exporter {{`{{`}} $labels.namespace {{`}}`}}/{{`{{`}} $labels.pod {{`}}`}} + runbook_url: {{ .Values.defaultRules.runbookUrl }}/general/nodenetworkinterfaceflapping + summary: Network interface is often changing its status + expr: changes(node_network_up{job="node-exporter",device!~"veth.+"}[2m]) > 2 + for: {{ dig "NodeNetworkInterfaceFlapping" "for" "2m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "NodeNetworkInterfaceFlapping" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.network }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.network }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node.rules.yaml new file mode 100644 index 0000000000..0bf9b8653e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/node.rules.yaml @@ -0,0 +1,109 @@ +{{- /* +Generated from 'node.rules' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.node }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "node.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: node.rules + rules: + - expr: |- + topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node, namespace, pod) ( + label_replace(kube_pod_info{job="{{ $kubeStateMetricsJob }}",node!=""}, "pod", "$1", "pod", "(.*)") + )) + record: 'node_namespace_pod:kube_pod_info:' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) ( + node_cpu_seconds_total{mode="idle",job="node-exporter"} + * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) group_left(node) + topk by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod) (1, node_namespace_pod:kube_pod_info:) + ) + record: node:node_num_cpu:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum( + node_memory_MemAvailable_bytes{job="node-exporter"} or + ( + node_memory_Buffers_bytes{job="node-exporter"} + + node_memory_Cached_bytes{job="node-exporter"} + + node_memory_MemFree_bytes{job="node-exporter"} + + node_memory_Slab_bytes{job="node-exporter"} + ) + ) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) + record: :node_memory_MemAvailable_bytes:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, node) ( + sum without (mode) ( + rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!="steal",job="node-exporter"}[5m]) + ) + ) + record: node:node_cpu_utilization:ratio_rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) ( + node:node_cpu_utilization:ratio_rate5m + ) + record: cluster:node_cpu:ratio_rate5m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.node }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.node }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/prometheus-operator.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/prometheus-operator.yaml new file mode 100644 index 0000000000..cb5c495877 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/prometheus-operator.yaml @@ -0,0 +1,253 @@ +{{- /* +Generated from 'prometheus-operator' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.prometheusOperator }} +{{- $operatorJob := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "operator" }} +{{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "prometheus-operator" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: prometheus-operator + rules: +{{- if not (.Values.defaultRules.disabled.PrometheusOperatorListErrors | default false) }} + - alert: PrometheusOperatorListErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} +{{- end }} + description: Errors while performing List operations in controller {{`{{`}}$labels.controller{{`}}`}} in {{`{{`}}$labels.namespace{{`}}`}} namespace. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorlisterrors + summary: Errors while performing list operations in controller. + expr: (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_list_operations_failed_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[10m])) / sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_list_operations_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[10m]))) > 0.4 + for: {{ dig "PrometheusOperatorListErrors" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOperatorListErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusOperatorWatchErrors | default false) }} + - alert: PrometheusOperatorWatchErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} +{{- end }} + description: Errors while performing watch operations in controller {{`{{`}}$labels.controller{{`}}`}} in {{`{{`}}$labels.namespace{{`}}`}} namespace. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorwatcherrors + summary: Errors while performing watch operations in controller. + expr: (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_watch_operations_failed_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m])) / sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_watch_operations_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) > 0.4 + for: {{ dig "PrometheusOperatorWatchErrors" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOperatorWatchErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusOperatorSyncFailed | default false) }} + - alert: PrometheusOperatorSyncFailed + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} +{{- end }} + description: Controller {{`{{`}} $labels.controller {{`}}`}} in {{`{{`}} $labels.namespace {{`}}`}} namespace fails to reconcile {{`{{`}} $value {{`}}`}} objects. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorsyncfailed + summary: Last controller reconciliation failed + expr: min_over_time(prometheus_operator_syncs{status="failed",job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusOperatorSyncFailed" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOperatorSyncFailed" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusOperatorReconcileErrors | default false) }} + - alert: PrometheusOperatorReconcileErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} +{{- end }} + description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of reconciling operations failed for {{`{{`}} $labels.controller {{`}}`}} controller in {{`{{`}} $labels.namespace {{`}}`}} namespace.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorreconcileerrors + summary: Errors while reconciling objects. + expr: (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_reconcile_errors_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) / (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_reconcile_operations_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) > 0.1 + for: {{ dig "PrometheusOperatorReconcileErrors" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOperatorReconcileErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusOperatorStatusUpdateErrors | default false) }} + - alert: PrometheusOperatorStatusUpdateErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} +{{- end }} + description: '{{`{{`}} $value | humanizePercentage {{`}}`}} of status update operations failed for {{`{{`}} $labels.controller {{`}}`}} controller in {{`{{`}} $labels.namespace {{`}}`}} namespace.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorstatusupdateerrors + summary: Errors while updating objects status. + expr: (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_status_update_errors_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) / (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (rate(prometheus_operator_status_update_operations_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]))) > 0.1 + for: {{ dig "PrometheusOperatorStatusUpdateErrors" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOperatorStatusUpdateErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusOperatorNodeLookupErrors | default false) }} + - alert: PrometheusOperatorNodeLookupErrors + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} +{{- end }} + description: Errors while reconciling Prometheus in {{`{{`}} $labels.namespace {{`}}`}} Namespace. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatornodelookuperrors + summary: Errors while reconciling Prometheus. + expr: rate(prometheus_operator_node_address_lookup_errors_total{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]) > 0.1 + for: {{ dig "PrometheusOperatorNodeLookupErrors" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOperatorNodeLookupErrors" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusOperatorNotReady | default false) }} + - alert: PrometheusOperatorNotReady + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} +{{- end }} + description: Prometheus operator in {{`{{`}} $labels.namespace {{`}}`}} namespace isn't ready to reconcile {{`{{`}} $labels.controller {{`}}`}} resources. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatornotready + summary: Prometheus operator not ready + expr: min by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,controller,namespace) (max_over_time(prometheus_operator_ready{job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]) == 0) + for: {{ dig "PrometheusOperatorNotReady" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOperatorNotReady" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusOperatorRejectedResources | default false) }} + - alert: PrometheusOperatorRejectedResources + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheusOperator | indent 8 }} +{{- end }} + description: Prometheus operator in {{`{{`}} $labels.namespace {{`}}`}} namespace rejected {{`{{`}} printf "%0.0f" $value {{`}}`}} {{`{{`}} $labels.controller {{`}}`}}/{{`{{`}} $labels.resource {{`}}`}} resources. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus-operator/prometheusoperatorrejectedresources + summary: Resources rejected by Prometheus operator + expr: min_over_time(prometheus_operator_managed_resources{state="rejected",job="{{ $operatorJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusOperatorRejectedResources" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOperatorRejectedResources" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheusOperator }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/prometheus.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/prometheus.yaml new file mode 100644 index 0000000000..0cc617ff77 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/prometheus.yaml @@ -0,0 +1,735 @@ +{{- /* +Generated from 'prometheus' group from https://github.com/prometheus-operator/kube-prometheus.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.defaultRules.rules.prometheus }} +{{- $prometheusJob := printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "prometheus" }} +{{- $namespace := printf "%s" (include "kube-prometheus-stack.namespace" .) }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "prometheus" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: prometheus + rules: +{{- if not (.Values.defaultRules.disabled.PrometheusBadConfig | default false) }} + - alert: PrometheusBadConfig + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed to reload its configuration. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusbadconfig + summary: Failed Prometheus configuration reload. + expr: |- + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + max_over_time(prometheus_config_last_reload_successful{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) == 0 + for: {{ dig "PrometheusBadConfig" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusBadConfig" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusSDRefreshFailure | default false) }} + - alert: PrometheusSDRefreshFailure + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed to refresh SD with mechanism {{`{{`}}$labels.mechanism{{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheussdrefreshfailure + summary: Failed Prometheus SD refresh. + expr: increase(prometheus_sd_refresh_failures_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[10m]) > 0 + for: {{ dig "PrometheusSDRefreshFailure" "for" "20m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusSDRefreshFailure" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusKubernetesListWatchFailures | default false) }} + - alert: PrometheusKubernetesListWatchFailures + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Kubernetes service discovery of Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is experiencing {{`{{`}} printf "%.0f" $value {{`}}`}} failures with LIST/WATCH requests to the Kubernetes API in the last 5 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheuskuberneteslistwatchfailures + summary: Requests in Kubernetes SD are failing. + expr: increase(prometheus_sd_kubernetes_failures_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusKubernetesListWatchFailures" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusKubernetesListWatchFailures" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusNotificationQueueRunningFull | default false) }} + - alert: PrometheusNotificationQueueRunningFull + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Alert notification queue of Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is running full. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusnotificationqueuerunningfull + summary: Prometheus alert notification queue predicted to run full in less than 30m. + expr: |- + # Without min_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + ( + predict_linear(prometheus_notifications_queue_length{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m], 60 * 30) + > + min_over_time(prometheus_notifications_queue_capacity{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) + ) + for: {{ dig "PrometheusNotificationQueueRunningFull" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusNotificationQueueRunningFull" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusErrorSendingAlertsToSomeAlertmanagers | default false) }} + - alert: PrometheusErrorSendingAlertsToSomeAlertmanagers + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: '{{`{{`}} printf "%.1f" $value {{`}}`}}% errors while sending alerts from Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} to Alertmanager {{`{{`}}$labels.alertmanager{{`}}`}}.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheuserrorsendingalertstosomealertmanagers + summary: Prometheus has encountered more than 1% errors sending alerts to a specific Alertmanager. + expr: |- + ( + rate(prometheus_notifications_errors_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) + / + rate(prometheus_notifications_sent_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) + ) + * 100 + > 1 + for: {{ dig "PrometheusErrorSendingAlertsToSomeAlertmanagers" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusErrorSendingAlertsToSomeAlertmanagers" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusNotConnectedToAlertmanagers | default false) }} + - alert: PrometheusNotConnectedToAlertmanagers + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is not connected to any Alertmanagers. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusnotconnectedtoalertmanagers + summary: Prometheus is not connected to any Alertmanagers. + expr: |- + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + max_over_time(prometheus_notifications_alertmanagers_discovered{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) < 1 + for: {{ dig "PrometheusNotConnectedToAlertmanagers" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusNotConnectedToAlertmanagers" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusTSDBReloadsFailing | default false) }} + - alert: PrometheusTSDBReloadsFailing + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has detected {{`{{`}}$value | humanize{{`}}`}} reload failures over the last 3h. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheustsdbreloadsfailing + summary: Prometheus has issues reloading blocks from disk. + expr: increase(prometheus_tsdb_reloads_failures_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[3h]) > 0 + for: {{ dig "PrometheusTSDBReloadsFailing" "for" "4h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusTSDBReloadsFailing" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusTSDBCompactionsFailing | default false) }} + - alert: PrometheusTSDBCompactionsFailing + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has detected {{`{{`}}$value | humanize{{`}}`}} compaction failures over the last 3h. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheustsdbcompactionsfailing + summary: Prometheus has issues compacting blocks. + expr: increase(prometheus_tsdb_compactions_failed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[3h]) > 0 + for: {{ dig "PrometheusTSDBCompactionsFailing" "for" "4h" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusTSDBCompactionsFailing" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusNotIngestingSamples | default false) }} + - alert: PrometheusNotIngestingSamples + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is not ingesting samples. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusnotingestingsamples + summary: Prometheus is not ingesting samples. + expr: |- + ( + sum without(type) (rate(prometheus_tsdb_head_samples_appended_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m])) <= 0 + and + ( + sum without(scrape_job) (prometheus_target_metadata_cache_entries{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}) > 0 + or + sum without(rule_group) (prometheus_rule_group_rules{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}) > 0 + ) + ) + for: {{ dig "PrometheusNotIngestingSamples" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusNotIngestingSamples" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusDuplicateTimestamps | default false) }} + - alert: PrometheusDuplicateTimestamps + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is dropping {{`{{`}} printf "%.4g" $value {{`}}`}} samples/s with different values but duplicated timestamp. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusduplicatetimestamps + summary: Prometheus is dropping samples with duplicate timestamps. + expr: rate(prometheus_target_scrapes_sample_duplicate_timestamp_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusDuplicateTimestamps" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusDuplicateTimestamps" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusOutOfOrderTimestamps | default false) }} + - alert: PrometheusOutOfOrderTimestamps + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} is dropping {{`{{`}} printf "%.4g" $value {{`}}`}} samples/s with timestamps arriving out of order. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusoutofordertimestamps + summary: Prometheus drops samples with out-of-order timestamps. + expr: rate(prometheus_target_scrapes_sample_out_of_order_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusOutOfOrderTimestamps" "for" "10m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusOutOfOrderTimestamps" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusRemoteStorageFailures | default false) }} + - alert: PrometheusRemoteStorageFailures + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} failed to send {{`{{`}} printf "%.1f" $value {{`}}`}}% of the samples to {{`{{`}} $labels.remote_name{{`}}`}}:{{`{{`}} $labels.url {{`}}`}} + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusremotestoragefailures + summary: Prometheus fails to send samples to remote storage. + expr: |- + ( + (rate(prometheus_remote_storage_failed_samples_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m])) + / + ( + (rate(prometheus_remote_storage_failed_samples_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m])) + + + (rate(prometheus_remote_storage_succeeded_samples_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) or rate(prometheus_remote_storage_samples_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m])) + ) + ) + * 100 + > 1 + for: {{ dig "PrometheusRemoteStorageFailures" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusRemoteStorageFailures" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusRemoteWriteBehind | default false) }} + - alert: PrometheusRemoteWriteBehind + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} remote write is {{`{{`}} printf "%.1f" $value {{`}}`}}s behind for {{`{{`}} $labels.remote_name{{`}}`}}:{{`{{`}} $labels.url {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusremotewritebehind + summary: Prometheus remote write is behind. + expr: |- + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + ( + max_over_time(prometheus_remote_storage_highest_timestamp_in_seconds{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) + - ignoring(remote_name, url) group_right + max_over_time(prometheus_remote_storage_queue_highest_sent_timestamp_seconds{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) + ) + > 120 + for: {{ dig "PrometheusRemoteWriteBehind" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusRemoteWriteBehind" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusRemoteWriteDesiredShards | default false) }} + - alert: PrometheusRemoteWriteDesiredShards + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} remote write desired shards calculation wants to run {{`{{`}} $value {{`}}`}} shards for queue {{`{{`}} $labels.remote_name{{`}}`}}:{{`{{`}} $labels.url {{`}}`}}, which is more than the max of {{`{{`}} printf `prometheus_remote_storage_shards_max{instance="%s",job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}` $labels.instance | query | first | value {{`}}`}}. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusremotewritedesiredshards + summary: Prometheus remote write desired shards calculation wants to run more than configured max shards. + expr: |- + # Without max_over_time, failed scrapes could create false negatives, see + # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details. + ( + max_over_time(prometheus_remote_storage_shards_desired{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) + > + max_over_time(prometheus_remote_storage_shards_max{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) + ) + for: {{ dig "PrometheusRemoteWriteDesiredShards" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusRemoteWriteDesiredShards" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusRuleFailures | default false) }} + - alert: PrometheusRuleFailures + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed to evaluate {{`{{`}} printf "%.0f" $value {{`}}`}} rules in the last 5m. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusrulefailures + summary: Prometheus is failing rule evaluations. + expr: increase(prometheus_rule_evaluation_failures_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusRuleFailures" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusRuleFailures" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusMissingRuleEvaluations | default false) }} + - alert: PrometheusMissingRuleEvaluations + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has missed {{`{{`}} printf "%.0f" $value {{`}}`}} rule group evaluations in the last 5m. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusmissingruleevaluations + summary: Prometheus is missing rule evaluations due to slow rule group evaluation. + expr: increase(prometheus_rule_group_iterations_missed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusMissingRuleEvaluations" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusMissingRuleEvaluations" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusTargetLimitHit | default false) }} + - alert: PrometheusTargetLimitHit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has dropped {{`{{`}} printf "%.0f" $value {{`}}`}} targets because the number of targets exceeded the configured target_limit. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheustargetlimithit + summary: Prometheus has dropped targets because some scrape configs have exceeded the targets limit. + expr: increase(prometheus_target_scrape_pool_exceeded_target_limit_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusTargetLimitHit" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusTargetLimitHit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusLabelLimitHit | default false) }} + - alert: PrometheusLabelLimitHit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has dropped {{`{{`}} printf "%.0f" $value {{`}}`}} targets because some samples exceeded the configured label_limit, label_name_length_limit or label_value_length_limit. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheuslabellimithit + summary: Prometheus has dropped targets because some scrape configs have exceeded the labels limit. + expr: increase(prometheus_target_scrape_pool_exceeded_label_limits_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusLabelLimitHit" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusLabelLimitHit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusScrapeBodySizeLimitHit | default false) }} + - alert: PrometheusScrapeBodySizeLimitHit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed {{`{{`}} printf "%.0f" $value {{`}}`}} scrapes in the last 5m because some targets exceeded the configured body_size_limit. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusscrapebodysizelimithit + summary: Prometheus has dropped some targets that exceeded body size limit. + expr: increase(prometheus_target_scrapes_exceeded_body_size_limit_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusScrapeBodySizeLimitHit" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusScrapeBodySizeLimitHit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusScrapeSampleLimitHit | default false) }} + - alert: PrometheusScrapeSampleLimitHit + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} has failed {{`{{`}} printf "%.0f" $value {{`}}`}} scrapes in the last 5m because some targets exceeded the configured sample_limit. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheusscrapesamplelimithit + summary: Prometheus has failed scrapes that have exceeded the configured sample limit. + expr: increase(prometheus_target_scrapes_exceeded_sample_limit_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0 + for: {{ dig "PrometheusScrapeSampleLimitHit" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusScrapeSampleLimitHit" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusTargetSyncFailure | default false) }} + - alert: PrometheusTargetSyncFailure + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: '{{`{{`}} printf "%.0f" $value {{`}}`}} targets in Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} have failed to sync because invalid configuration was supplied.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheustargetsyncfailure + summary: Prometheus has failed to sync targets. + expr: increase(prometheus_target_sync_failed_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[30m]) > 0 + for: {{ dig "PrometheusTargetSyncFailure" "for" "5m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusTargetSyncFailure" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusHighQueryLoad | default false) }} + - alert: PrometheusHighQueryLoad + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} query API has less than 20% available capacity in its query engine for the last 15 minutes. + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheushighqueryload + summary: Prometheus is reaching its maximum capacity serving concurrent requests. + expr: avg_over_time(prometheus_engine_queries{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) / max_over_time(prometheus_engine_queries_concurrent_max{job="{{ $prometheusJob }}",namespace="{{ $namespace }}"}[5m]) > 0.8 + for: {{ dig "PrometheusHighQueryLoad" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusHighQueryLoad" "severity" "warning" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- if not (.Values.defaultRules.disabled.PrometheusErrorSendingAlertsToAnyAlertmanager | default false) }} + - alert: PrometheusErrorSendingAlertsToAnyAlertmanager + annotations: +{{- if .Values.defaultRules.additionalRuleAnnotations }} +{{ toYaml .Values.defaultRules.additionalRuleAnnotations | indent 8 }} +{{- end }} +{{- if .Values.defaultRules.additionalRuleGroupAnnotations.prometheus }} +{{ toYaml .Values.defaultRules.additionalRuleGroupAnnotations.prometheus | indent 8 }} +{{- end }} + description: '{{`{{`}} printf "%.1f" $value {{`}}`}}% minimum errors while sending alerts from Prometheus {{`{{`}}$labels.namespace{{`}}`}}/{{`{{`}}$labels.pod{{`}}`}} to any Alertmanager.' + runbook_url: {{ .Values.defaultRules.runbookUrl }}/prometheus/prometheuserrorsendingalertstoanyalertmanager + summary: Prometheus encounters more than 3% errors sending alerts to any Alertmanager. + expr: |- + min without (alertmanager) ( + rate(prometheus_notifications_errors_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}",alertmanager!~``}[5m]) + / + rate(prometheus_notifications_sent_total{job="{{ $prometheusJob }}",namespace="{{ $namespace }}",alertmanager!~``}[5m]) + ) + * 100 + > 3 + for: {{ dig "PrometheusErrorSendingAlertsToAnyAlertmanager" "for" "15m" .Values.customRules }} + {{- with .Values.defaultRules.keepFiringFor }} + keep_firing_for: "{{ . }}" + {{- end }} + labels: + severity: {{ dig "PrometheusErrorSendingAlertsToAnyAlertmanager" "severity" "critical" .Values.customRules }} + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.prometheus }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/windows.node.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/windows.node.rules.yaml new file mode 100644 index 0000000000..7c25553861 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/windows.node.rules.yaml @@ -0,0 +1,301 @@ +{{- /* +Generated from 'windows.node.rules' group from https://github.com/kubernetes-monitoring/kubernetes-mixin.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.windowsMonitoring.enabled .Values.defaultRules.rules.windows }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "windows.node.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: windows.node.rules + rules: + - expr: |- + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) ( + windows_system_system_up_time{job="windows-exporter"} + ) + record: node:windows_node:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + count by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) (sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, core) ( + windows_cpu_time_total{job="windows-exporter"} + )) + record: node:windows_node_num_cpu:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: 1 - avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (rate(windows_cpu_time_total{job="windows-exporter",mode="idle"}[1m])) + record: :windows_node_cpu_utilisation:avg1m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + 1 - avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( + rate(windows_cpu_time_total{job="windows-exporter",mode="idle"}[1m]) + ) + record: node:windows_node_cpu_utilisation:avg1m + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + 1 - + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (windows_memory_available_bytes{job="windows-exporter"}) + / + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (windows_os_visible_memory_bytes{job="windows-exporter"}) + record: ':windows_node_memory_utilisation:' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (windows_memory_available_bytes{job="windows-exporter"} + windows_memory_cache_bytes{job="windows-exporter"}) + record: :windows_node_memory_MemFreeCached_bytes:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: (windows_memory_cache_bytes{job="windows-exporter"} + windows_memory_modified_page_list_bytes{job="windows-exporter"} + windows_memory_standby_cache_core_bytes{job="windows-exporter"} + windows_memory_standby_cache_normal_priority_bytes{job="windows-exporter"} + windows_memory_standby_cache_reserve_bytes{job="windows-exporter"}) + record: node:windows_node_memory_totalCached_bytes:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (windows_os_visible_memory_bytes{job="windows-exporter"}) + record: :windows_node_memory_MemTotal_bytes:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( + (windows_memory_available_bytes{job="windows-exporter"}) + ) + record: node:windows_node_memory_bytes_available:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( + windows_os_visible_memory_bytes{job="windows-exporter"} + ) + record: node:windows_node_memory_bytes_total:sum + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + (node:windows_node_memory_bytes_total:sum - node:windows_node_memory_bytes_available:sum) + / + scalar(sum(node:windows_node_memory_bytes_total:sum)) + record: node:windows_node_memory_utilisation:ratio + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: 1 - (node:windows_node_memory_bytes_available:sum / node:windows_node_memory_bytes_total:sum) + record: 'node:windows_node_memory_utilisation:' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: irate(windows_memory_swap_page_operations_total{job="windows-exporter"}[5m]) + record: node:windows_node_memory_swap_io_pages:irate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (irate(windows_logical_disk_read_seconds_total{job="windows-exporter"}[1m]) + + irate(windows_logical_disk_write_seconds_total{job="windows-exporter"}[1m]) + ) + record: :windows_node_disk_utilisation:avg_irate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + avg by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( + (irate(windows_logical_disk_read_seconds_total{job="windows-exporter"}[1m]) + + irate(windows_logical_disk_write_seconds_total{job="windows-exporter"}[1m])) + ) + record: node:windows_node_disk_utilisation:avg_irate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster,instance,volume)( + (windows_logical_disk_size_bytes{job="windows-exporter"} + - windows_logical_disk_free_bytes{job="windows-exporter"}) + / windows_logical_disk_size_bytes{job="windows-exporter"} + ) + record: 'node:windows_node_filesystem_usage:' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance, volume) (windows_logical_disk_free_bytes{job="windows-exporter"} / windows_logical_disk_size_bytes{job="windows-exporter"}) + record: 'node:windows_node_filesystem_avail:' + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (irate(windows_net_bytes_total{job="windows-exporter"}[1m])) + record: :windows_node_net_utilisation:sum_irate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( + (irate(windows_net_bytes_total{job="windows-exporter"}[1m])) + ) + record: node:windows_node_net_utilisation:sum_irate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (irate(windows_net_packets_received_discarded_total{job="windows-exporter"}[1m])) + + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster) (irate(windows_net_packets_outbound_discarded_total{job="windows-exporter"}[1m])) + record: :windows_node_net_saturation:sum_irate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, instance) ( + (irate(windows_net_packets_received_discarded_total{job="windows-exporter"}[1m]) + + irate(windows_net_packets_outbound_discarded_total{job="windows-exporter"}[1m])) + ) + record: node:windows_node_net_saturation:sum_irate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/windows.pod.rules.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/windows.pod.rules.yaml new file mode 100644 index 0000000000..86340b5c05 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/rules-1.14/windows.pod.rules.yaml @@ -0,0 +1,158 @@ +{{- /* +Generated from 'windows.pod.rules' group from https://github.com/kubernetes-monitoring/kubernetes-mixin.git +Do not change in-place! In order to change this file first read following link: +https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack/hack +*/ -}} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if and (semverCompare ">=1.14.0-0" $kubeTargetVersion) (semverCompare "<9.9.9-9" $kubeTargetVersion) .Values.defaultRules.create .Values.windowsMonitoring.enabled .Values.defaultRules.rules.windows }} +{{- $kubeStateMetricsJob := include "kube-prometheus-stack-kube-state-metrics.name" . }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" .) "windows.pod.rules" | trunc 63 | trimSuffix "-" }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.defaultRules.labels }} +{{ toYaml .Values.defaultRules.labels | indent 4 }} +{{- end }} +{{- if .Values.defaultRules.annotations }} + annotations: +{{ toYaml .Values.defaultRules.annotations | indent 4 }} +{{- end }} +spec: + groups: + - name: windows.pod.rules + rules: + - expr: windows_container_available{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) + record: windows_pod_container_available + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: windows_container_cpu_usage_seconds_total{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) + record: windows_container_total_runtime + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: windows_container_memory_usage_commit_bytes{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) + record: windows_container_memory_usage + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: windows_container_memory_usage_private_working_set_bytes{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) + record: windows_container_private_working_set_usage + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: windows_container_network_receive_bytes_total{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) + record: windows_container_network_received_bytes_total + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: windows_container_network_transmit_bytes_total{job="windows-exporter", container_id != ""} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container_id, cluster) group_left(container, pod, namespace) max(kube_pod_container_info{job="{{ $kubeStateMetricsJob }}", container_id != ""}) by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container, container_id, pod, namespace, cluster) + record: windows_container_network_transmitted_bytes_total + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, container) ( + kube_pod_container_resource_requests{resource="memory",job="{{ $kubeStateMetricsJob }}"} + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container,pod,namespace,cluster) (windows_pod_container_available) + record: kube_pod_windows_container_resource_memory_request + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: kube_pod_container_resource_limits{resource="memory",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container,pod,namespace,cluster) (windows_pod_container_available) + record: kube_pod_windows_container_resource_memory_limit + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + max by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, container) ( + kube_pod_container_resource_requests{resource="cpu",job="{{ $kubeStateMetricsJob }}"} + ) * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container,pod,namespace,cluster) (windows_pod_container_available) + record: kube_pod_windows_container_resource_cpu_cores_request + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: kube_pod_container_resource_limits{resource="cpu",job="{{ $kubeStateMetricsJob }}"} * on ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}container,pod,namespace,cluster) (windows_pod_container_available) + record: kube_pod_windows_container_resource_cpu_cores_limit + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + - expr: |- + sum by ({{ range $.Values.defaultRules.additionalAggregationLabels }}{{ . }},{{ end }}cluster, namespace, pod, container) ( + rate(windows_container_total_runtime{}[5m]) + ) + record: namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate + {{- if or .Values.defaultRules.additionalRuleLabels .Values.defaultRules.additionalRuleGroupLabels.windows }} + labels: + {{- with .Values.defaultRules.additionalRuleLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.defaultRules.additionalRuleGroupLabels.windows }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/secret.yaml new file mode 100644 index 0000000000..e4a1e73c7b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/secret.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.prometheusSpec.thanos .Values.prometheus.prometheusSpec.thanos.objectStorageConfig}} +{{- if and .Values.prometheus.prometheusSpec.thanos.objectStorageConfig.secret (not .Values.prometheus.prometheusSpec.thanos.objectStorageConfig.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus + app.kubernetes.io/component: prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: + object-storage-configs.yaml: {{ toYaml .Values.prometheus.prometheusSpec.thanos.objectStorageConfig.secret | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/service.yaml new file mode 100644 index 0000000000..bfabebe7b9 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/service.yaml @@ -0,0 +1,84 @@ +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if .Values.prometheus.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus + self-monitor: {{ .Values.prometheus.serviceMonitor.selfMonitor | quote }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.prometheus.service.labels }} +{{ toYaml .Values.prometheus.service.labels | indent 4 }} +{{- end }} +{{- if .Values.prometheus.service.annotations }} + annotations: +{{ toYaml .Values.prometheus.service.annotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.prometheus.service.clusterIP }} + clusterIP: {{ .Values.prometheus.service.clusterIP }} +{{- end }} +{{- if .Values.prometheus.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.prometheus.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.prometheus.service.ipDualStack.ipFamilyPolicy }} +{{- end }} +{{- if .Values.prometheus.service.externalIPs }} + externalIPs: +{{ toYaml .Values.prometheus.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.prometheus.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.prometheus.service.loadBalancerIP }} +{{- end }} +{{- if .Values.prometheus.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.prometheus.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if ne .Values.prometheus.service.type "ClusterIP" }} + externalTrafficPolicy: {{ .Values.prometheus.service.externalTrafficPolicy }} +{{- end }} + ports: + - name: {{ .Values.prometheus.prometheusSpec.portName }} + {{- if eq .Values.prometheus.service.type "NodePort" }} + nodePort: {{ .Values.prometheus.service.nodePort }} + {{- end }} + port: {{ .Values.prometheus.service.port }} + targetPort: {{ .Values.prometheus.service.targetPort }} + - name: reloader-web + {{- if semverCompare "> 1.20.0-0" $kubeTargetVersion }} + appProtocol: http + {{- end }} + port: {{ .Values.prometheus.service.reloaderWebPort }} + targetPort: reloader-web + {{- if .Values.prometheus.thanosIngress.enabled }} + - name: grpc + {{- if eq .Values.prometheus.service.type "NodePort" }} + nodePort: {{ .Values.prometheus.thanosIngress.nodePort }} + {{- end }} + port: {{ .Values.prometheus.thanosIngress.servicePort }} + targetPort: {{ .Values.prometheus.thanosIngress.servicePort }} + {{- end }} +{{- if .Values.prometheus.service.additionalPorts }} +{{ toYaml .Values.prometheus.service.additionalPorts | indent 2 }} +{{- end }} + publishNotReadyAddresses: {{ .Values.prometheus.service.publishNotReadyAddresses }} + selector: + {{- if .Values.prometheus.agentMode }} + app.kubernetes.io/name: prometheus-agent + {{- else }} + app.kubernetes.io/name: prometheus + {{- end }} + operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} +{{- if .Values.prometheus.service.sessionAffinity }} + sessionAffinity: {{ .Values.prometheus.service.sessionAffinity }} +{{- end }} +{{- if eq .Values.prometheus.service.sessionAffinity "ClientIP" }} + sessionAffinityConfig: + clientIP: + timeoutSeconds: {{ .Values.prometheus.service.sessionAffinityConfig.clientIP.timeoutSeconds }} +{{- end }} + type: "{{ .Values.prometheus.service.type }}" +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceThanosSidecar.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceThanosSidecar.yaml new file mode 100644 index 0000000000..87fae7b4f9 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceThanosSidecar.yaml @@ -0,0 +1,43 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.thanosService.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-thanos-discovery + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-thanos-discovery +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.prometheus.thanosService.labels }} +{{ toYaml .Values.prometheus.thanosService.labels | indent 4 }} +{{- end }} +{{- if .Values.prometheus.thanosService.annotations }} + annotations: +{{ toYaml .Values.prometheus.thanosService.annotations | indent 4 }} +{{- end }} +spec: + type: {{ .Values.prometheus.thanosService.type }} + clusterIP: {{ .Values.prometheus.thanosService.clusterIP }} +{{- if .Values.prometheus.thanosService.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.prometheus.thanosService.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.prometheus.thanosService.ipDualStack.ipFamilyPolicy }} +{{- end }} +{{- if ne .Values.prometheus.thanosService.type "ClusterIP" }} + externalTrafficPolicy: {{ .Values.prometheus.thanosService.externalTrafficPolicy }} +{{- end }} + ports: + - name: {{ .Values.prometheus.thanosService.portName }} + port: {{ .Values.prometheus.thanosService.port }} + targetPort: {{ .Values.prometheus.thanosService.targetPort }} + {{- if eq .Values.prometheus.thanosService.type "NodePort" }} + nodePort: {{ .Values.prometheus.thanosService.nodePort }} + {{- end }} + - name: {{ .Values.prometheus.thanosService.httpPortName }} + port: {{ .Values.prometheus.thanosService.httpPort }} + targetPort: {{ .Values.prometheus.thanosService.targetHttpPort }} + {{- if eq .Values.prometheus.thanosService.type "NodePort" }} + nodePort: {{ .Values.prometheus.thanosService.httpNodePort }} + {{- end }} + selector: + app.kubernetes.io/name: prometheus + operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceThanosSidecarExternal.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceThanosSidecarExternal.yaml new file mode 100644 index 0000000000..453eed7f1b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceThanosSidecarExternal.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.thanosServiceExternal.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-thanos-external + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.prometheus.thanosServiceExternal.labels }} +{{ toYaml .Values.prometheus.thanosServiceExternal.labels | indent 4 }} +{{- end }} +{{- if .Values.prometheus.thanosServiceExternal.annotations }} + annotations: +{{ toYaml .Values.prometheus.thanosServiceExternal.annotations | indent 4 }} +{{- end }} +spec: + type: {{ .Values.prometheus.thanosServiceExternal.type }} +{{- if .Values.prometheus.thanosServiceExternal.loadBalancerIP }} + loadBalancerIP: {{ .Values.prometheus.thanosServiceExternal.loadBalancerIP }} +{{- end }} +{{- if .Values.prometheus.thanosServiceExternal.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.prometheus.thanosServiceExternal.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if ne .Values.prometheus.thanosServiceExternal.type "ClusterIP" }} + externalTrafficPolicy: {{ .Values.prometheus.thanosServiceExternal.externalTrafficPolicy }} +{{- end }} + ports: + - name: {{ .Values.prometheus.thanosServiceExternal.portName }} + port: {{ .Values.prometheus.thanosServiceExternal.port }} + targetPort: {{ .Values.prometheus.thanosServiceExternal.targetPort }} + {{- if eq .Values.prometheus.thanosServiceExternal.type "NodePort" }} + nodePort: {{ .Values.prometheus.thanosServiceExternal.nodePort }} + {{- end }} + - name: {{ .Values.prometheus.thanosServiceExternal.httpPortName }} + port: {{ .Values.prometheus.thanosServiceExternal.httpPort }} + targetPort: {{ .Values.prometheus.thanosServiceExternal.targetHttpPort }} + {{- if eq .Values.prometheus.thanosServiceExternal.type "NodePort" }} + nodePort: {{ .Values.prometheus.thanosServiceExternal.httpNodePort }} + {{- end }} + selector: + app.kubernetes.io/name: prometheus + operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceaccount.yaml new file mode 100644 index 0000000000..e97b989bbd --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kube-prometheus-stack.prometheus.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus + app.kubernetes.io/name: {{ template "kube-prometheus-stack.name" . }}-prometheus + app.kubernetes.io/component: prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- if .Values.prometheus.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.prometheus.serviceAccount.annotations | indent 4 }} +{{- end }} +automountServiceAccountToken: {{ .Values.prometheus.serviceAccount.automountServiceAccountToken }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{ include "kube-prometheus-stack.imagePullSecrets" . | trim | indent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitor.yaml new file mode 100644 index 0000000000..a36f3e33ca --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitor.yaml @@ -0,0 +1,97 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.serviceMonitor.selfMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- with .Values.prometheus.serviceMonitor.additionalLabels }} +{{- toYaml . | nindent 4 }} +{{- end }} +spec: + {{- include "servicemonitor.scrapeLimits" .Values.prometheus.serviceMonitor | nindent 2 }} + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-prometheus + release: {{ $.Release.Name | quote }} + self-monitor: "true" + namespaceSelector: + matchNames: + - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} + endpoints: + - port: {{ .Values.prometheus.prometheusSpec.portName }} + {{- if .Values.prometheus.serviceMonitor.interval }} + interval: {{ .Values.prometheus.serviceMonitor.interval }} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.scheme }} + scheme: {{ .Values.prometheus.serviceMonitor.scheme }} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.tlsConfig }} + tlsConfig: {{- toYaml .Values.prometheus.serviceMonitor.tlsConfig | nindent 6 }} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.serviceMonitor.bearerTokenFile }} + {{- end }} + path: "{{ trimSuffix "/" .Values.prometheus.prometheusSpec.routePrefix }}/metrics" + metricRelabelings: + {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} + {{- tpl (toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 6) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.relabelings }} + relabelings: {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 6 }} + {{- end }} + - port: reloader-web + {{- if .Values.prometheus.serviceMonitor.interval }} + interval: {{ .Values.prometheus.serviceMonitor.interval }} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.scheme }} + scheme: {{ .Values.prometheus.serviceMonitor.scheme }} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.tlsConfig }} + tlsConfig: {{- toYaml .Values.prometheus.serviceMonitor.tlsConfig | nindent 6 }} + {{- end }} + path: "/metrics" + {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- tpl (toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 6) . }} + {{- end }} + {{- if .Values.prometheus.serviceMonitor.relabelings }} + relabelings: {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 6 }} + {{- end }} + {{- range .Values.prometheus.serviceMonitor.additionalEndpoints }} + - port: {{ .port }} + {{- if or $.Values.prometheus.serviceMonitor.interval .interval }} + interval: {{ default $.Values.prometheus.serviceMonitor.interval .interval }} + {{- end }} + {{- if or $.Values.prometheus.serviceMonitor.proxyUrl .proxyUrl }} + proxyUrl: {{ default $.Values.prometheus.serviceMonitor.proxyUrl .proxyUrl }} + {{- end }} + {{- if or $.Values.prometheus.serviceMonitor.scheme .scheme }} + scheme: {{ default $.Values.prometheus.serviceMonitor.scheme .scheme }} + {{- end }} + {{- if or $.Values.prometheus.serviceMonitor.bearerTokenFile .bearerTokenFile }} + bearerTokenFile: {{ default $.Values.prometheus.serviceMonitor.bearerTokenFile .bearerTokenFile }} + {{- end }} + {{- if or $.Values.prometheus.serviceMonitor.tlsConfig .tlsConfig }} + tlsConfig: {{- default $.Values.prometheus.serviceMonitor.tlsConfig .tlsConfig | toYaml | nindent 6 }} + {{- end }} + path: {{ .path }} + {{- if or $.Values.prometheus.serviceMonitor.metricRelabelings .metricRelabelings }} + metricRelabelings: {{- tpl (default $.Values.prometheus.serviceMonitor.metricRelabelings .metricRelabelings | toYaml | nindent 6) . }} + {{- end }} + {{- if or $.Values.prometheus.serviceMonitor.relabelings .relabelings }} + relabelings: {{- default $.Values.prometheus.serviceMonitor.relabelings .relabelings | toYaml | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitorThanosSidecar.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitorThanosSidecar.yaml new file mode 100644 index 0000000000..0f70aabb58 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitorThanosSidecar.yaml @@ -0,0 +1,55 @@ +{{- if and .Values.prometheus.thanosService.enabled .Values.prometheus.thanosServiceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-thanos-sidecar + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-thanos-sidecar +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- with .Values.prometheus.thanosServiceMonitor.additionalLabels }} +{{- toYaml . | nindent 4 }} +{{- end }} +spec: + {{- include "servicemonitor.scrapeLimits" .Values.prometheus.thanosServiceMonitor | nindent 2 }} + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-thanos-discovery + release: {{ $.Release.Name | quote }} + namespaceSelector: + matchNames: + - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} + endpoints: + - port: {{ .Values.prometheus.thanosService.httpPortName }} + {{- if .Values.prometheus.thanosServiceMonitor.interval }} + interval: {{ .Values.prometheus.thanosServiceMonitor.interval }} + {{- end }} + {{- if .Values.prometheus.thanosServiceMonitor.scheme }} + scheme: {{ .Values.prometheus.thanosServiceMonitor.scheme }} + {{- end }} + {{- if .Values.prometheus.thanosServiceMonitor.tlsConfig }} + tlsConfig: {{ toYaml .Values.prometheus.thanosServiceMonitor.tlsConfig | nindent 6 }} + {{- end }} + {{- if .Values.prometheus.thanosServiceMonitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.prometheus.thanosServiceMonitor.bearerTokenFile }} + {{- end }} + path: "/metrics" + metricRelabelings: + {{- if .Values.prometheus.thanosServiceMonitor.metricRelabelings}} + {{ tpl (toYaml .Values.prometheus.thanosServiceMonitor.metricRelabelings | indent 6) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.prometheus.thanosServiceMonitor.relabelings }} + relabelings: +{{ toYaml .Values.prometheus.thanosServiceMonitor.relabelings | indent 6 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitors.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitors.yaml new file mode 100644 index 0000000000..a7a301babc --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/servicemonitors.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.additionalServiceMonitors }} +apiVersion: v1 +kind: List +items: +{{- range .Values.prometheus.additionalServiceMonitors }} + - apiVersion: monitoring.coreos.com/v1 + kind: ServiceMonitor + metadata: + name: {{ .name }} + namespace: {{ template "kube-prometheus-stack.namespace" $ }} + labels: + app: {{ template "kube-prometheus-stack.name" $ }}-prometheus +{{ include "kube-prometheus-stack.labels" $ | indent 8 }} + {{- if .additionalLabels }} +{{ toYaml .additionalLabels | indent 8 }} + {{- end }} + spec: + {{- include "servicemonitor.scrapeLimits" . | nindent 6 }} + endpoints: +{{ toYaml .endpoints | indent 8 }} + {{- if .jobLabel }} + jobLabel: {{ .jobLabel }} + {{- end }} + {{- if .namespaceSelector }} + namespaceSelector: +{{ toYaml .namespaceSelector | indent 8 }} + {{- end }} + selector: +{{ toYaml .selector | indent 8 }} + {{- if .targetLabels }} + targetLabels: +{{ toYaml .targetLabels | indent 8 }} + {{- end }} + {{- if .podTargetLabels }} + podTargetLabels: +{{ toYaml .podTargetLabels | indent 8 }} + {{- end }} + {{- if .metricRelabelings }} + metricRelabelings: +{{ toYaml .metricRelabelings | indent 8 }} + {{- end }} + {{- if .relabelings }} + relabelings: +{{ toYaml .relabelings | indent 8 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceperreplica.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceperreplica.yaml new file mode 100644 index 0000000000..3a88b2df34 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/prometheus/serviceperreplica.yaml @@ -0,0 +1,58 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.servicePerReplica.enabled }} +{{- $count := .Values.prometheus.prometheusSpec.replicas | int -}} +{{- $serviceValues := .Values.prometheus.servicePerReplica -}} +apiVersion: v1 +kind: List +metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-serviceperreplica + namespace: {{ template "kube-prometheus-stack.namespace" . }} +items: +{{- range $i, $e := until $count }} + - apiVersion: v1 + kind: Service + metadata: + name: {{ include "kube-prometheus-stack.fullname" $ }}-prometheus-{{ $i }} + namespace: {{ template "kube-prometheus-stack.namespace" $ }} + labels: + app: {{ include "kube-prometheus-stack.name" $ }}-prometheus +{{ include "kube-prometheus-stack.labels" $ | indent 8 }} + {{- if $serviceValues.annotations }} + annotations: +{{ toYaml $serviceValues.annotations | indent 8 }} + {{- end }} + spec: + {{- if $serviceValues.clusterIP }} + clusterIP: {{ $serviceValues.clusterIP }} + {{- end }} + {{- if $serviceValues.ipDualStack.enabled }} + ipFamilies: {{ toYaml $serviceValues.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ $serviceValues.ipDualStack.ipFamilyPolicy }} + {{- end }} + {{- if $serviceValues.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := $serviceValues.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} + {{- end }} + {{- if ne $serviceValues.type "ClusterIP" }} + externalTrafficPolicy: {{ $serviceValues.externalTrafficPolicy }} + {{- end }} + ports: + - name: {{ $.Values.prometheus.prometheusSpec.portName }} + {{- if eq $serviceValues.type "NodePort" }} + nodePort: {{ $serviceValues.nodePort }} + {{- end }} + port: {{ $serviceValues.port }} + targetPort: {{ $serviceValues.targetPort }} + selector: + {{- if $.Values.prometheus.agentMode }} + app.kubernetes.io/name: prometheus-agent + statefulset.kubernetes.io/pod-name: prom-agent-{{ include "kube-prometheus-stack.prometheus.crname" $ }}-{{ $i }} + {{- else }} + app.kubernetes.io/name: prometheus + statefulset.kubernetes.io/pod-name: prometheus-{{ include "kube-prometheus-stack.prometheus.crname" $ }}-{{ $i }} + {{- end }} + operator.prometheus.io/name: {{ template "kube-prometheus-stack.prometheus.crname" $ }} + type: "{{ $serviceValues.type }}" +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/clusterrole.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/clusterrole.yaml new file mode 100644 index 0000000000..56ca9f5eae --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/clusterrole.yaml @@ -0,0 +1,135 @@ +{{- if and .Values.global.rbac.create .Values.global.rbac.userRoles.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: monitoring-admin + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} + {{- if .Values.global.rbac.userRoles.aggregateToDefaultRoles }} + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- end }} +rules: +- apiGroups: + - monitoring.coreos.com + resources: + - alertmanagers + - prometheuses + - prometheuses/finalizers + - alertmanagers/finalizers + verbs: + - 'get' + - 'list' + - 'watch' +- apiGroups: + - monitoring.coreos.com + resources: + - thanosrulers + - thanosrulers/finalizers + - servicemonitors + - podmonitors + - prometheusrules + - podmonitors + - probes + - probes/finalizers + - alertmanagerconfigs + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: monitoring-edit + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} + {{- if .Values.global.rbac.userRoles.aggregateToDefaultRoles }} + rbac.authorization.k8s.io/aggregate-to-edit: "true" + {{- end }} +rules: +- apiGroups: + - monitoring.coreos.com + resources: + - alertmanagers + - prometheuses + - prometheuses/finalizers + - alertmanagers/finalizers + verbs: + - 'get' + - 'list' + - 'watch' +- apiGroups: + - monitoring.coreos.com + resources: + - thanosrulers + - thanosrulers/finalizers + - servicemonitors + - podmonitors + - prometheusrules + - podmonitors + - probes + - alertmanagerconfigs + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: monitoring-view + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} + {{- if .Values.global.rbac.userRoles.aggregateToDefaultRoles }} + rbac.authorization.k8s.io/aggregate-to-view: "true" + {{- end }} +rules: +- apiGroups: + - monitoring.coreos.com + resources: + - alertmanagers + - prometheuses + - prometheuses/finalizers + - alertmanagers/finalizers + - thanosrulers + - thanosrulers/finalizers + - servicemonitors + - podmonitors + - prometheusrules + - podmonitors + - probes + - probes/finalizers + - alertmanagerconfigs + verbs: + - 'get' + - 'list' + - 'watch' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: monitoring-ui-view + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - services/proxy + resourceNames: + - "http:{{ template "kube-prometheus-stack.fullname" . }}-prometheus:{{ .Values.prometheus.service.port }}" + - "https:{{ template "kube-prometheus-stack.fullname" . }}-prometheus:{{ .Values.prometheus.service.port }}" + - "http:{{ template "kube-prometheus-stack.fullname" . }}-alertmanager:{{ .Values.alertmanager.service.port }}" + - "https:{{ template "kube-prometheus-stack.fullname" . }}-alertmanager:{{ .Values.alertmanager.service.port }}" +{{- if .Values.grafana.enabled }} + - "http:{{ include "call-nested" (list . "grafana" "grafana.fullname") }}:{{ .Values.grafana.service.port }}" + - "https:{{ include "call-nested" (list . "grafana" "grafana.fullname") }}:{{ .Values.grafana.service.port }}" +{{- end }} + verbs: + - 'get' + - 'create' +- apiGroups: + - "" + resourceNames: + - {{ template "kube-prometheus-stack.fullname" . }}-prometheus + - {{ template "kube-prometheus-stack.fullname" . }}-alertmanager +{{- if .Values.grafana.enabled }} + - {{ include "call-nested" (list . "grafana" "grafana.fullname") }} +{{- end }} + resources: + - endpoints + verbs: + - list +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/config-role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/config-role.yaml new file mode 100644 index 0000000000..f48ffc827e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/config-role.yaml @@ -0,0 +1,48 @@ +{{- if and .Values.global.rbac.create .Values.global.rbac.userRoles.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: monitoring-config-admin + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: monitoring-config-edit + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: monitoring-config-view + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - 'get' + - 'list' + - 'watch' +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboard-role.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboard-role.yaml new file mode 100644 index 0000000000..d2f81976a2 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboard-role.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.global.rbac.create .Values.global.rbac.userRoles.create .Values.grafana.enabled }} +{{- if .Values.grafana.defaultDashboardsEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: monitoring-dashboard-admin + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: monitoring-dashboard-edit + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: monitoring-dashboard-view + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - 'get' + - 'list' + - 'watch' +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml new file mode 100644 index 0000000000..7b51a0bf7a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/addons/ingress-nginx-dashboard.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled .Values.ingressNginx.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: {{ printf "%s-%s" (include "kube-prometheus-stack.fullname" $) "ingress-nginx" | trunc 63 | trimSuffix "-" }} + {{- if .Values.grafana.sidecar.dashboards.annotations }} + annotations: {{ toYaml .Values.grafana.sidecar.dashboards.annotations | nindent 4 }} + {{- end }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/ingress-nginx/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml new file mode 100644 index 0000000000..d73b257451 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/cluster-dashboards.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-default-dashboards-cluster + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/cluster/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml new file mode 100644 index 0000000000..8865efa932 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/default-dashboard.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-default-dashboards-home + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/home/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml new file mode 100644 index 0000000000..9b05cea2e8 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fleet-dashboards.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-fleet-dashboards + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/fleet/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentbit-dashboard.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentbit-dashboard.yaml new file mode 100644 index 0000000000..b2d1bfcb73 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentbit-dashboard.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled .Values.loggingMonitors.fluentbit.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-fluentbit-dashboard + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/logging/fluentbit.json").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentd-dashboard.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentd-dashboard.yaml new file mode 100644 index 0000000000..66c9cb845a --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/fluentd-dashboard.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled .Values.loggingMonitors.fluentd.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-fluentd-dashboard + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/logging/fluentd.json").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml new file mode 100644 index 0000000000..2afae10ef7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/k8s-dashboards.yaml @@ -0,0 +1,31 @@ +{{- $files := (.Files.Glob "files/rancher/k8s/*").AsConfig }} +{{- $filesDict := (fromYaml $files) }} +{{- if not (include "exporter.kubeEtcd.enabled" .) }} +{{- $filesDict = (unset $filesDict "rancher-etcd-nodes.json") -}} +{{- $filesDict = (unset $filesDict "rancher-etcd.json") -}} +{{- end }} +{{- if not (include "exporter.kubeControllerManager.enabled" .) }} +{{- $filesDict = (unset $filesDict "rancher-k8s-components-nodes.json") -}} +{{- $filesDict = (unset $filesDict "rancher-k8s-components.json") -}} +{{- else }} +{{- $_ := (set $filesDict "rancher-k8s-components-nodes.json" (get $filesDict "rancher-k8s-components-nodes.json" | replace "kube-controller-manager" (include "exporter.kubeControllerManager.jobName" .))) -}} +{{- $_ := (set $filesDict "rancher-k8s-components.json" (get $filesDict "rancher-k8s-components.json" | replace "kube-controller-manager" (include "exporter.kubeControllerManager.jobName" .))) -}} +{{- end }} +{{ $files = (toYaml $filesDict) }} +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-default-dashboards-k8s + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ $files | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml new file mode 100644 index 0000000000..172c36e9d1 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/nodes-dashboards.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-default-dashboards-nodes + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/nodes/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml new file mode 100644 index 0000000000..19836ec4e4 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/performance-dashboards.yaml @@ -0,0 +1,18 @@ +{{- $selector := (include "rancher.serviceMonitor.selector" .) -}} +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled .Values.rancherMonitoring.enabled $selector }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-default-dashboards-performance-debugging + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/performance/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml new file mode 100644 index 0000000000..940f18869b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/pods-dashboards.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-default-dashboards-pods + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/pods/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml new file mode 100644 index 0000000000..d146dacdd0 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/dashboards/rancher/workload-dashboards.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Values.grafana.defaultDashboards.namespace }} + name: rancher-default-dashboards-workloads + annotations: +{{ toYaml .Values.grafana.sidecar.dashboards.annotations | indent 4 }} + labels: + {{- if $.Values.grafana.sidecar.dashboards.label }} + {{ $.Values.grafana.sidecar.dashboards.label }}: "1" + {{- end }} + app: {{ template "kube-prometheus-stack.name" $ }}-grafana +{{ include "kube-prometheus-stack.labels" $ | indent 4 }} +data: +{{ (.Files.Glob "files/rancher/workloads/*").AsConfig | indent 2 }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml new file mode 100644 index 0000000000..90d24c2061 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/fleet/servicemonitor.yaml @@ -0,0 +1,53 @@ +{{- if .Values.rancherMonitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} + name: monitoring-fleet-controller + namespace: cattle-fleet-system +spec: + endpoints: + - port: metrics + metricRelabelings: + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} + jobLabel: fleet + selector: + matchLabels: + app: fleet-controller +{{- end }} +--- +{{- if .Values.rancherMonitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} + name: monitoring-gitops-controller + namespace: cattle-fleet-system +spec: + endpoints: + - port: metrics + metricRelabelings: + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} + jobLabel: gitops + selector: + matchLabels: + app: gitjob +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/network-policy.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/network-policy.yaml new file mode 100644 index 0000000000..a1d3eb083c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/network-policy.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rke2IngressNginx.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + annotations: + np.rke2.io/ingress: resolved + name: rke2-ingress-network-policy + namespace: {{ include "rke2-ingress-nginx.namespace" . }} +spec: + ingress: + - ports: + - port: {{ .Values.rke2IngressNginx.metricsPort }} + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: rke2-ingress-nginx + policyTypes: + - Ingress + {{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml new file mode 100644 index 0000000000..53a9ad6897 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/service.yaml @@ -0,0 +1,27 @@ +{{- if and (not .Values.ingressNginx.enabled) (.Values.rkeIngressNginx.enabled) }} +{{- fail "Cannot set .Values.rkeIngressNginx.enabled=true when .Values.ingressNginx.enabled=false" }} +{{- end }} +{{- if and .Values.ingressNginx.enabled (not .Values.rkeIngressNginx.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-ingress-nginx + labels: + app: {{ template "kube-prometheus-stack.name" . }}-ingress-nginx + jobLabel: ingress-nginx +{{ include "kube-prometheus-stack.labels" . | indent 4 }} + namespace: {{ .Values.ingressNginx.namespace }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.ingressNginx.service.port }} + protocol: TCP + targetPort: {{ .Values.ingressNginx.service.targetPort }} + selector: + {{- if .Values.ingressNginx.service.selector }} +{{ toYaml .Values.ingressNginx.service.selector | indent 4 }} + {{- else }} + app: ingress-nginx + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml new file mode 100644 index 0000000000..b0f92e63b5 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/ingress-nginx/servicemonitor.yaml @@ -0,0 +1,49 @@ +{{- if and (not .Values.ingressNginx.enabled) (.Values.rkeIngressNginx.enabled) }} +{{- fail "Cannot set .Values.rkeIngressNginx.enabled=true when .Values.ingressNginx.enabled=false" }} +{{- end }} +{{- if and .Values.ingressNginx.enabled (not .Values.rkeIngressNginx.enabled) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-ingress-nginx + namespace: {{ .Values.ingressNginx.namespace }} + labels: + app: {{ template "kube-prometheus-stack.name" . }}-ingress-nginx +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + jobLabel: jobLabel + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.name" . }}-ingress-nginx + release: {{ $.Release.Name | quote }} + namespaceSelector: + matchNames: + - {{ .Values.ingressNginx.namespace }} + endpoints: + - port: http-metrics + {{- if .Values.ingressNginx.serviceMonitor.interval}} + interval: {{ .Values.ingressNginx.serviceMonitor.interval }} + {{- end }} + {{- if .Values.ingressNginx.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.ingressNginx.serviceMonitor.proxyUrl}} + {{- end }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + metricRelabelings: + {{- if .Values.ingressNginx.serviceMonitor.metricRelabelings }} + {{ tpl (toYaml .Values.ingressNginx.serviceMonitor.metricRelabelings | indent 4) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} +{{- if .Values.ingressNginx.serviceMonitor.relabelings }} + relabelings: +{{ toYaml .Values.ingressNginx.serviceMonitor.relabelings | indent 4 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml new file mode 100644 index 0000000000..1fba8f23f7 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/exporters/rancher/servicemonitor.yaml @@ -0,0 +1,58 @@ +{{- $selector := (include "rancher.serviceMonitor.selector" .) -}} +{{- if and .Values.rancherMonitoring.enabled $selector }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: {{ include "kube-prometheus-stack.labels" . | nindent 4 }} + name: rancher + namespace: cattle-system +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + port: http + tlsConfig: + caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecureSkipVerify: true + serverName: rancher + metricRelabelings: + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} + jobLabel: rancher +{{- if .Values.rancherMonitoring.namespaceSelector }} + namespaceSelector: {{ .Values.rancherMonitoring.namespaceSelector | toYaml | nindent 4 }} +{{- end }} + selector: {{ include "rancher.serviceMonitor.selector" . | nindent 4 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-rancher-metrics +rules: +- apiGroups: + - management.cattle.io + resources: + - ranchermetrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-rancher-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kube-prometheus-stack.fullname" . }}-rancher-metrics +subjects: + - kind: ServiceAccount + name: {{ template "kube-prometheus-stack.fullname" . }}-prometheus + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/hardened.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/hardened.yaml new file mode 100644 index 0000000000..63bac7fd42 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/hardened.yaml @@ -0,0 +1,91 @@ +{{- $namespaces := dict "_0" .Release.Namespace -}} +{{- if and .Values.grafana.enabled .Values.grafana.defaultDashboardsEnabled (not .Values.grafana.defaultDashboards.useExistingNamespace) -}} +{{- $_ := set $namespaces "_1" .Values.grafana.defaultDashboards.namespace -}} +{{- end -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Chart.Name }}-patch-sa + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }}-patch-sa + annotations: + "helm.sh/hook": post-install, post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, before-hook-creation +spec: + template: + metadata: + name: {{ .Chart.Name }}-patch-sa + labels: + app: {{ .Chart.Name }}-patch-sa + spec: + serviceAccountName: {{ .Chart.Name }}-patch-sa + securityContext: + runAsNonRoot: true + runAsUser: 1000 + restartPolicy: Never + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + containers: + {{- range $_, $ns := $namespaces }} + - name: patch-sa-{{ $ns }} + image: {{ template "system_default_registry" $ }}{{ $.Values.global.kubectl.repository }}:{{ $.Values.global.kubectl.tag }} + imagePullPolicy: {{ $.Values.global.kubectl.pullPolicy }} + command: ["kubectl", "patch", "serviceaccount", "default", "-p", "{\"automountServiceAccountToken\": false}"] + args: ["-n", "{{ $ns }}"] + {{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Chart.Name }}-patch-sa + labels: + app: {{ .Chart.Name }}-patch-sa +rules: +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: ['get', 'patch'] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Chart.Name }}-patch-sa + labels: + app: {{ .Chart.Name }}-patch-sa +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Chart.Name }}-patch-sa +subjects: +- kind: ServiceAccount + name: {{ .Chart.Name }}-patch-sa + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Chart.Name }}-patch-sa + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }}-patch-sa +--- +{{- if .Values.hardened.k3s.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: rancher-monitoring-coredns-allow-all + namespace: kube-system +spec: + ingress: + - {} + egress: + - {} + policyTypes: + - Ingress + - Egress + podSelector: + matchLabels: + k8s-app: kube-dns +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/configmap.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/configmap.yaml new file mode 100644 index 0000000000..53cb898214 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/configmap.yaml @@ -0,0 +1,13 @@ +{{- if .Values.upgrade.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + namespace: {{ template "kube-prometheus-stack.namespace" . }} + annotations: + "helm.sh/hook": pre-upgrade, pre-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "0" +data: +{{ (.Files.Glob "files/upgrade/scripts/*").AsConfig | indent 2 }} +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/job.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/job.yaml new file mode 100644 index 0000000000..8f2771740c --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/job.yaml @@ -0,0 +1,46 @@ +{{- if .Values.upgrade.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + annotations: + "helm.sh/hook": pre-upgrade, pre-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "2" +spec: + template: + metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + labels: + app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + spec: + serviceAccountName: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + securityContext: + runAsNonRoot: false + runAsUser: 0 + restartPolicy: Never + nodeSelector: {{ include "linux-node-selector" . | nindent 8 }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + containers: + - name: run-scripts + image: {{ template "system_default_registry" . }}{{ .Values.upgrade.image.repository }}:{{ .Values.upgrade.image.tag }} + imagePullPolicy: {{ $.Values.global.kubectl.pullPolicy }} + command: + - /bin/sh + - -c + - > + for s in $(find /etc/scripts -type f); do + echo "Running $s..."; + cat $s | bash + done; + volumeMounts: + - name: upgrade + mountPath: /etc/scripts + volumes: + - name: upgrade + configMap: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/rbac.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/rbac.yaml new file mode 100644 index 0000000000..46bdd3a36b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/rancher-monitoring/upgrade/rbac.yaml @@ -0,0 +1,86 @@ +{{- if .Values.upgrade.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + annotations: + "helm.sh/hook": pre-upgrade, pre-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded + "helm.sh/hook-weight": "1" +rules: +- apiGroups: + - apps + resources: + - deployments + - daemonsets + - statefulsets + verbs: + - 'list' + - 'delete' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + annotations: + "helm.sh/hook": pre-upgrade, pre-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "1" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade +subjects: +- kind: ServiceAccount + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + namespace: {{ template "kube-prometheus-stack.namespace" . }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + labels: + app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + annotations: + "helm.sh/hook": pre-upgrade, pre-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "1" +rules: +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + labels: + app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + annotations: + "helm.sh/hook": pre-upgrade, pre-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "1" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade +subjects: +- kind: ServiceAccount + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + namespace: {{ template "kube-prometheus-stack.namespace" . }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.fullname" . }}-upgrade + annotations: + "helm.sh/hook": pre-upgrade, pre-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "1" +{{- end }} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/extrasecret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/extrasecret.yaml new file mode 100644 index 0000000000..587fca2dca --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/extrasecret.yaml @@ -0,0 +1,20 @@ +{{- if .Values.thanosRuler.extraSecret.data -}} +{{- $secretName := printf "%s-extra" (include "kube-prometheus-stack.thanosRuler.name" . ) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ default $secretName .Values.thanosRuler.extraSecret.name }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- if .Values.thanosRuler.extraSecret.annotations }} + annotations: +{{ toYaml .Values.thanosRuler.extraSecret.annotations | indent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + app.kubernetes.io/component: thanos-ruler +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: +{{- range $key, $val := .Values.thanosRuler.extraSecret.data }} + {{ $key }}: {{ $val | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/ingress.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/ingress.yaml new file mode 100644 index 0000000000..e245ad448e --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/ingress.yaml @@ -0,0 +1,77 @@ +{{- if and .Values.thanosRuler.enabled .Values.thanosRuler.ingress.enabled }} +{{- $pathType := .Values.thanosRuler.ingress.pathType | default "ImplementationSpecific" }} +{{- $serviceName := include "kube-prometheus-stack.thanosRuler.name" . }} +{{- $servicePort := .Values.thanosRuler.service.port -}} +{{- $routePrefix := list .Values.thanosRuler.thanosRulerSpec.routePrefix }} +{{- $paths := .Values.thanosRuler.ingress.paths | default $routePrefix -}} +{{- $apiIsStable := eq (include "kube-prometheus-stack.ingress.isStable" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "kube-prometheus-stack.ingress.supportsPathType" .) "true" -}} +apiVersion: {{ include "kube-prometheus-stack.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $serviceName }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} +{{- if .Values.thanosRuler.ingress.annotations }} + annotations: + {{- tpl (toYaml .Values.thanosRuler.ingress.annotations) . | nindent 4 }} +{{- end }} + labels: + app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} +{{- if .Values.thanosRuler.ingress.labels }} +{{ toYaml .Values.thanosRuler.ingress.labels | indent 4 }} +{{- end }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + {{- if $apiIsStable }} + {{- if .Values.thanosRuler.ingress.ingressClassName }} + ingressClassName: {{ .Values.thanosRuler.ingress.ingressClassName }} + {{- end }} + {{- end }} + rules: + {{- if .Values.thanosRuler.ingress.hosts }} + {{- range $host := .Values.thanosRuler.ingress.hosts }} + - host: {{ tpl $host $ }} + http: + paths: + {{- range $p := $paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- else }} + - http: + paths: + {{- range $p := $paths }} + - path: {{ tpl $p $ }} + {{- if and $pathType $ingressSupportsPathType }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- if .Values.thanosRuler.ingress.tls }} + tls: +{{ tpl (toYaml .Values.thanosRuler.ingress.tls | indent 4) . }} + {{- end -}} +{{- end -}} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/podDisruptionBudget.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/podDisruptionBudget.yaml new file mode 100644 index 0000000000..c28f914647 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/podDisruptionBudget.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.thanosRuler.enabled .Values.thanosRuler.podDisruptionBudget.enabled }} +apiVersion: {{ include "kube-prometheus-stack.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +spec: + {{- if .Values.thanosRuler.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.thanosRuler.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.thanosRuler.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.thanosRuler.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: thanos-ruler + thanos-ruler: {{ template "kube-prometheus-stack.thanosRuler.crname" . }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/ruler.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/ruler.yaml new file mode 100644 index 0000000000..94dc60be3f --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/ruler.yaml @@ -0,0 +1,200 @@ +{{- if .Values.thanosRuler.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ThanosRuler +metadata: + name: {{ template "kube-prometheus-stack.thanosRuler.crname" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ include "kube-prometheus-stack.thanosRuler.name" . }} +{{- include "kube-prometheus-stack.labels" . | indent 4 -}} +{{- if .Values.thanosRuler.annotations }} + annotations: +{{ toYaml .Values.thanosRuler.annotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.thanosRuler.thanosRulerSpec.image }} + {{- $registry := include "monitoring_registry" . | default .Values.thanosRuler.thanosRulerSpec.image.registry -}} + {{- if and .Values.thanosRuler.thanosRulerSpec.image.tag .Values.thanosRuler.thanosRulerSpec.image.sha }} + image: "{{ $registry }}/{{ .Values.thanosRuler.thanosRulerSpec.image.repository }}:{{ .Values.thanosRuler.thanosRulerSpec.image.tag }}@sha256:{{ .Values.thanosRuler.thanosRulerSpec.image.sha }}" + {{- else if .Values.thanosRuler.thanosRulerSpec.image.sha }} + image: "{{ $registry }}/{{ .Values.thanosRuler.thanosRulerSpec.image.repository }}@sha256:{{ .Values.thanosRuler.thanosRulerSpec.image.sha }}" + {{- else if .Values.thanosRuler.thanosRulerSpec.image.tag }} + image: "{{ $registry }}/{{ .Values.thanosRuler.thanosRulerSpec.image.repository }}:{{ .Values.thanosRuler.thanosRulerSpec.image.tag }}" + {{- else }} + image: "{{ $registry }}/{{ .Values.thanosRuler.thanosRulerSpec.image.repository }}" + {{- end }} + {{- if .Values.thanosRuler.thanosRulerSpec.image.sha }} + sha: {{ .Values.thanosRuler.thanosRulerSpec.image.sha }} + {{- end }} +{{- end }} + replicas: {{ .Values.thanosRuler.thanosRulerSpec.replicas }} + listenLocal: {{ .Values.thanosRuler.thanosRulerSpec.listenLocal }} + serviceAccountName: {{ template "kube-prometheus-stack.thanosRuler.serviceAccountName" . }} +{{- if .Values.thanosRuler.thanosRulerSpec.externalPrefix }} + externalPrefix: "{{ tpl .Values.thanosRuler.thanosRulerSpec.externalPrefix . }}" +{{- else if and .Values.thanosRuler.ingress.enabled .Values.thanosRuler.ingress.hosts }} + externalPrefix: "http://{{ tpl (index .Values.thanosRuler.ingress.hosts 0) . }}{{ .Values.thanosRuler.thanosRulerSpec.routePrefix }}" +{{- else if .Values.thanosRuler.thanosRulerSpec.externalPrefixNilUsesHelmValues }} + externalPrefix: "http://{{ template "kube-prometheus-stack.thanosRuler.name" . }}.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.thanosRuler.service.port }}" +{{- end }} + nodeSelector: {{ include "linux-node-selector" . | nindent 4 }} +{{- if .Values.thanosRuler.thanosRulerSpec.additionalArgs }} + additionalArgs: +{{ tpl (toYaml .Values.thanosRuler.thanosRulerSpec.additionalArgs) $ | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.nodeSelector }} + nodeSelector: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.nodeSelector | indent 4 }} +{{- end }} + paused: {{ .Values.thanosRuler.thanosRulerSpec.paused }} + logFormat: {{ .Values.thanosRuler.thanosRulerSpec.logFormat | quote }} + logLevel: {{ .Values.thanosRuler.thanosRulerSpec.logLevel | quote }} + retention: {{ .Values.thanosRuler.thanosRulerSpec.retention | quote }} +{{- if .Values.thanosRuler.thanosRulerSpec.evaluationInterval }} + evaluationInterval: {{ .Values.thanosRuler.thanosRulerSpec.evaluationInterval }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.ruleNamespaceSelector }} + ruleNamespaceSelector: +{{ tpl (toYaml .Values.thanosRuler.thanosRulerSpec.ruleNamespaceSelector | indent 4) . }} +{{ else }} + ruleNamespaceSelector: {} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.ruleSelector }} + ruleSelector: +{{ tpl (toYaml .Values.thanosRuler.thanosRulerSpec.ruleSelector | indent 4) .}} +{{- else if .Values.thanosRuler.thanosRulerSpec.ruleSelectorNilUsesHelmValues }} + ruleSelector: + matchLabels: + release: {{ $.Release.Name | quote }} +{{ else }} + ruleSelector: {} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.alertQueryUrl }} + alertQueryUrl: "{{ .Values.thanosRuler.thanosRulerSpec.alertQueryUrl }}" +{{- end}} +{{- if .Values.thanosRuler.thanosRulerSpec.alertmanagersUrl }} + alertmanagersUrl: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.alertmanagersUrl | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.alertmanagersConfig.existingSecret }} + alertmanagersConfig: + key: "{{.Values.thanosRuler.thanosRulerSpec.alertmanagersConfig.existingSecret.key }}" + name: "{{.Values.thanosRuler.thanosRulerSpec.alertmanagersConfig.existingSecret.name }}" +{{- else if .Values.thanosRuler.thanosRulerSpec.alertmanagersConfig.secret }} + alertmanagersConfig: + key: alertmanager-configs.yaml + name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.queryEndpoints }} + queryEndpoints: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.queryEndpoints | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.queryConfig.existingSecret }} + queryConfig: + key: "{{.Values.thanosRuler.thanosRulerSpec.queryConfig.existingSecret.key }}" + name: "{{.Values.thanosRuler.thanosRulerSpec.queryConfig.existingSecret.name }}" +{{- else if .Values.thanosRuler.thanosRulerSpec.queryConfig.secret }} + queryConfig: + key: query-configs.yaml + name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.resources }} + resources: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.resources | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.routePrefix }} + routePrefix: "{{ .Values.thanosRuler.thanosRulerSpec.routePrefix }}" +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.securityContext }} + securityContext: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.securityContext | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.storage }} + storage: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.storage | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.objectStorageConfig.existingSecret }} + objectStorageConfig: + key: "{{.Values.thanosRuler.thanosRulerSpec.objectStorageConfig.existingSecret.key }}" + name: "{{.Values.thanosRuler.thanosRulerSpec.objectStorageConfig.existingSecret.name }}" +{{- else if .Values.thanosRuler.thanosRulerSpec.objectStorageConfig.secret }} + objectStorageConfig: + key: object-storage-configs.yaml + name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.labels }} + labels: +{{ tpl (toYaml .Values.thanosRuler.thanosRulerSpec.labels) $ | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.podMetadata }} + podMetadata: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.podMetadata | indent 4 }} +{{- end }} +{{- if or .Values.thanosRuler.thanosRulerSpec.podAntiAffinity .Values.thanosRuler.thanosRulerSpec.affinity }} + affinity: +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.affinity }} +{{ toYaml .Values.thanosRuler.thanosRulerSpec.affinity | indent 4 }} +{{- end }} +{{- if eq .Values.thanosRuler.thanosRulerSpec.podAntiAffinity "hard" }} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: {{ .Values.thanosRuler.thanosRulerSpec.podAntiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - {key: app.kubernetes.io/name, operator: In, values: [thanos-ruler]} + - {key: thanos-ruler, operator: In, values: [{{ template "kube-prometheus-stack.thanosRuler.crname" . }}]} +{{- else if eq .Values.thanosRuler.thanosRulerSpec.podAntiAffinity "soft" }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: {{ .Values.thanosRuler.thanosRulerSpec.podAntiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - {key: app.kubernetes.io/name, operator: In, values: [thanos-ruler]} + - {key: thanos-ruler, operator: In, values: [{{ template "kube-prometheus-stack.thanosRuler.crname" . }}]} +{{- end }} + tolerations: {{ include "linux-node-tolerations" . | nindent 4 }} +{{- if .Values.thanosRuler.thanosRulerSpec.tolerations }} +{{ toYaml .Values.thanosRuler.thanosRulerSpec.tolerations | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.topologySpreadConstraints | indent 4 }} +{{- end }} +{{- if .Values.global.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.global.imagePullSecrets | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.containers }} + containers: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.containers | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.initContainers }} + initContainers: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.initContainers | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.priorityClassName }} + priorityClassName: {{.Values.thanosRuler.thanosRulerSpec.priorityClassName }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.volumes }} + volumes: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.volumes | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.volumeMounts }} + volumeMounts: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.volumeMounts | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.thanosRulerSpec.alertDropLabels }} + alertDropLabels: +{{ toYaml .Values.thanosRuler.thanosRulerSpec.alertDropLabels | indent 4 }} +{{- end }} + portName: {{ .Values.thanosRuler.thanosRulerSpec.portName }} +{{- with .Values.thanosRuler.thanosRulerSpec.additionalConfig }} + {{- tpl (toYaml .) $ | nindent 2 }} +{{- end }} +{{- with .Values.thanosRuler.thanosRulerSpec.additionalConfigString }} + {{- tpl . $ | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/secret.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/secret.yaml new file mode 100644 index 0000000000..acab7fd9ae --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/secret.yaml @@ -0,0 +1,26 @@ +{{- if .Values.thanosRuler.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ include "kube-prometheus-stack.thanosRuler.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +data: + {{- with .Values.thanosRuler.thanosRulerSpec.alertmanagersConfig }} + {{- if and .secret (not .existingSecret) }} + alertmanager-configs.yaml: {{ toYaml .secret | b64enc | quote }} + {{- end }} + {{- end }} + {{- with .Values.thanosRuler.thanosRulerSpec.objectStorageConfig }} + {{- if and .secret (not .existingSecret) }} + object-storage-configs.yaml: {{ toYaml .secret | b64enc | quote }} + {{- end }} + {{- end }} + {{- with .Values.thanosRuler.thanosRulerSpec.queryConfig }} + {{- if and .secret (not .existingSecret) }} + query-configs.yaml: {{ toYaml .secret | b64enc | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/service.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/service.yaml new file mode 100644 index 0000000000..e2cca29188 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/service.yaml @@ -0,0 +1,57 @@ +{{- if .Values.thanosRuler.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + self-monitor: {{ .Values.thanosRuler.serviceMonitor.selfMonitor | quote }} +{{- include "kube-prometheus-stack.labels" . | indent 4 -}} +{{- if .Values.thanosRuler.service.labels }} +{{ toYaml .Values.thanosRuler.service.labels | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.service.annotations }} + annotations: +{{ toYaml .Values.thanosRuler.service.annotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.thanosRuler.service.clusterIP }} + clusterIP: {{ .Values.thanosRuler.service.clusterIP }} +{{- end }} +{{- if .Values.thanosRuler.service.ipDualStack.enabled }} + ipFamilies: {{ toYaml .Values.thanosRuler.service.ipDualStack.ipFamilies | nindent 4 }} + ipFamilyPolicy: {{ .Values.thanosRuler.service.ipDualStack.ipFamilyPolicy }} +{{- end }} +{{- if .Values.thanosRuler.service.externalIPs }} + externalIPs: +{{ toYaml .Values.thanosRuler.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.thanosRuler.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.thanosRuler.service.loadBalancerIP }} +{{- end }} +{{- if .Values.thanosRuler.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.thanosRuler.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} +{{- if ne .Values.thanosRuler.service.type "ClusterIP" }} + externalTrafficPolicy: {{ .Values.thanosRuler.service.externalTrafficPolicy }} +{{- end }} + ports: + - name: {{ .Values.thanosRuler.thanosRulerSpec.portName }} + {{- if eq .Values.thanosRuler.service.type "NodePort" }} + nodePort: {{ .Values.thanosRuler.service.nodePort }} + {{- end }} + port: {{ .Values.thanosRuler.service.port }} + targetPort: {{ .Values.thanosRuler.service.targetPort }} + protocol: TCP +{{- if .Values.thanosRuler.service.additionalPorts }} +{{ toYaml .Values.thanosRuler.service.additionalPorts | indent 2 }} +{{- end }} + selector: + app.kubernetes.io/name: thanos-ruler + thanos-ruler: {{ template "kube-prometheus-stack.thanosRuler.crname" . }} + type: "{{ .Values.thanosRuler.service.type }}" +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/serviceaccount.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/serviceaccount.yaml new file mode 100644 index 0000000000..b58f1cd4df --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/serviceaccount.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.thanosRuler.enabled .Values.thanosRuler.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kube-prometheus-stack.thanosRuler.serviceAccountName" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + app.kubernetes.io/name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + app.kubernetes.io/component: thanos-ruler +{{- include "kube-prometheus-stack.labels" . | indent 4 -}} +{{- if .Values.thanosRuler.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.thanosRuler.serviceAccount.annotations | indent 4 }} +{{- end }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{ toYaml .Values.global.imagePullSecrets | indent 2 }} +{{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/servicemonitor.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/servicemonitor.yaml new file mode 100644 index 0000000000..d26ddce93b --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/thanos-ruler/servicemonitor.yaml @@ -0,0 +1,82 @@ +{{- if and .Values.thanosRuler.enabled .Values.thanosRuler.serviceMonitor.selfMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + namespace: {{ template "kube-prometheus-stack.namespace" . }} + labels: + app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} +{{ include "kube-prometheus-stack.labels" . | indent 4 }} +{{- with .Values.thanosRuler.serviceMonitor.additionalLabels }} +{{- toYaml . | nindent 4 }} +{{- end }} +spec: + {{- include "servicemonitor.scrapeLimits" .Values.thanosRuler.serviceMonitor | nindent 2 }} + selector: + matchLabels: + app: {{ template "kube-prometheus-stack.thanosRuler.name" . }} + release: {{ $.Release.Name | quote }} + self-monitor: {{ .Values.thanosRuler.serviceMonitor.selfMonitor | quote }} + namespaceSelector: + matchNames: + - {{ printf "%s" (include "kube-prometheus-stack.namespace" .) | quote }} + endpoints: + - port: {{ .Values.thanosRuler.thanosRulerSpec.portName }} + {{- if .Values.thanosRuler.serviceMonitor.interval }} + interval: {{ .Values.thanosRuler.serviceMonitor.interval }} + {{- end }} + {{- if .Values.thanosRuler.serviceMonitor.proxyUrl }} + proxyUrl: {{ .Values.thanosRuler.serviceMonitor.proxyUrl}} + {{- end }} + {{- if .Values.thanosRuler.serviceMonitor.scheme }} + scheme: {{ .Values.thanosRuler.serviceMonitor.scheme }} + {{- end }} + {{- if .Values.thanosRuler.serviceMonitor.bearerTokenFile }} + bearerTokenFile: {{ .Values.thanosRuler.serviceMonitor.bearerTokenFile }} + {{- end }} + {{- if .Values.thanosRuler.serviceMonitor.tlsConfig }} + tlsConfig: {{- toYaml .Values.thanosRuler.serviceMonitor.tlsConfig | nindent 6 }} + {{- end }} + path: "{{ trimSuffix "/" .Values.thanosRuler.thanosRulerSpec.routePrefix }}/metrics" + {{- if .Values.thanosRuler.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- tpl (toYaml .Values.thanosRuler.serviceMonitor.metricRelabelings | nindent 6) . }} + {{- end }} + {{ if .Values.global.cattle.clusterId }} + - sourceLabels: [__address__] + targetLabel: cluster_id + replacement: {{ .Values.global.cattle.clusterId }} + {{- end }} + {{ if .Values.global.cattle.clusterName}} + - sourceLabels: [__address__] + targetLabel: cluster_name + replacement: {{ .Values.global.cattle.clusterName }} + {{- end }} + {{- if .Values.thanosRuler.serviceMonitor.relabelings }} + relabelings: {{- toYaml .Values.thanosRuler.serviceMonitor.relabelings | nindent 6 }} + {{- end }} + {{- range .Values.thanosRuler.serviceMonitor.additionalEndpoints }} + - port: {{ .port }} + {{- if or $.Values.thanosRuler.serviceMonitor.interval .interval }} + interval: {{ default $.Values.thanosRuler.serviceMonitor.interval .interval }} + {{- end }} + {{- if or $.Values.thanosRuler.serviceMonitor.proxyUrl .proxyUrl }} + proxyUrl: {{ default $.Values.thanosRuler.serviceMonitor.proxyUrl .proxyUrl }} + {{- end }} + {{- if or $.Values.thanosRuler.serviceMonitor.scheme .scheme }} + scheme: {{ default $.Values.thanosRuler.serviceMonitor.scheme .scheme }} + {{- end }} + {{- if or $.Values.thanosRuler.serviceMonitor.bearerTokenFile .bearerTokenFile }} + bearerTokenFile: {{ default $.Values.thanosRuler.serviceMonitor.bearerTokenFile .bearerTokenFile }} + {{- end }} + {{- if or $.Values.thanosRuler.serviceMonitor.tlsConfig .tlsConfig }} + tlsConfig: {{- default $.Values.thanosRuler.serviceMonitor.tlsConfig .tlsConfig | toYaml | nindent 6 }} + {{- end }} + path: {{ .path }} + {{- if or $.Values.thanosRuler.serviceMonitor.metricRelabelings .metricRelabelings }} + metricRelabelings: {{- tpl (default $.Values.thanosRuler.serviceMonitor.metricRelabelings .metricRelabelings | toYaml | nindent 6) . }} + {{- end }} + {{- if or $.Values.thanosRuler.serviceMonitor.relabelings .relabelings }} + relabelings: {{- default $.Values.thanosRuler.serviceMonitor.relabelings .relabelings | toYaml | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/validate-install-crd.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/validate-install-crd.yaml new file mode 100644 index 0000000000..6fcb8b3a69 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/validate-install-crd.yaml @@ -0,0 +1,23 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +# {{- $found := dict -}} +# {{- set $found "monitoring.coreos.com/v1alpha1/AlertmanagerConfig" false -}} +# {{- set $found "monitoring.coreos.com/v1/Alertmanager" false -}} +# {{- set $found "monitoring.coreos.com/v1/PodMonitor" false -}} +# {{- set $found "monitoring.coreos.com/v1/Probe" false -}} +# {{- set $found "monitoring.coreos.com/v1alpha1/PrometheusAgent" false -}} +# {{- set $found "monitoring.coreos.com/v1/Prometheus" false -}} +# {{- set $found "monitoring.coreos.com/v1/PrometheusRule" false -}} +# {{- set $found "monitoring.coreos.com/v1alpha1/ScrapeConfig" false -}} +# {{- set $found "monitoring.coreos.com/v1/ServiceMonitor" false -}} +# {{- set $found "monitoring.coreos.com/v1/ThanosRuler" false -}} +# {{- range .Capabilities.APIVersions -}} +# {{- if hasKey $found (toString .) -}} +# {{- set $found (toString .) true -}} +# {{- end -}} +# {{- end -}} +# {{- range $_, $exists := $found -}} +# {{- if (eq $exists false) -}} +# {{- required "Required CRDs are missing. Please install the corresponding CRD chart before installing this chart." "" -}} +# {{- end -}} +# {{- end -}} +#{{- end -}} \ No newline at end of file diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/validate-psp-install.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/validate-psp-install.yaml new file mode 100644 index 0000000000..b115feb1af --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/templates/validate-psp-install.yaml @@ -0,0 +1,2 @@ +#{{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} +#{{- end }} diff --git a/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/values.yaml b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/values.yaml new file mode 100644 index 0000000000..da7b580657 --- /dev/null +++ b/charts/rancher-monitoring/105.1.0-rc.2+up61.3.2/values.yaml @@ -0,0 +1,5567 @@ +# Default values for kube-prometheus-stack. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Rancher Monitoring Configuration + +## Configuration for prometheus-adapter +## ref: https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-adapter +## +prometheus-adapter: + enabled: true + prometheus: + # Change this if you change the namespaceOverride or nameOverride of prometheus-operator + url: http://rancher-monitoring-prometheus.cattle-monitoring-system.svc + port: 9090 + +## RKE PushProx Monitoring +## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox +## +rkeControllerManager: + enabled: false + metricsPort: 10257 # default to secure port as of k8s >= 1.22 + component: kube-controller-manager + clients: + https: + enabled: true + insecureSkipVerify: true + useServiceAccountCredentials: true + port: 10011 + useLocalhost: true + nodeSelector: + node-role.kubernetes.io/controlplane: "true" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + kubeVersionOverrides: + - constraint: "< 1.22" + values: + metricsPort: 10252 # default to insecure port in k8s < 1.22 + clients: + https: + enabled: false + insecureSkipVerify: false + useServiceAccountCredentials: false + +rkeScheduler: + enabled: false + metricsPort: 10259 + component: kube-scheduler + clients: + https: + enabled: true + insecureSkipVerify: true + useServiceAccountCredentials: true + port: 10012 + useLocalhost: true + nodeSelector: + node-role.kubernetes.io/controlplane: "true" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + kubeVersionOverrides: + - constraint: "< 1.23" + values: + metricsPort: 10251 # default to insecure port in k8s < 1.23 + clients: + https: + enabled: false + insecureSkipVerify: false + useServiceAccountCredentials: false + +rkeProxy: + enabled: false + metricsPort: 10249 + component: kube-proxy + clients: + port: 10013 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +rkeEtcd: + enabled: false + metricsPort: 2379 + component: kube-etcd + clients: + port: 10014 + https: + enabled: true + certDir: /etc/kubernetes/ssl + certFile: kube-etcd-*.pem + keyFile: kube-etcd-*-key.pem + caCertFile: kube-ca.pem + seLinuxOptions: + # Gives rkeEtcd permissions to read files in /etc/kubernetes/* + # Type is defined in https://github.com/rancher/rancher-selinux + type: rke_kubereader_t + nodeSelector: + node-role.kubernetes.io/etcd: "true" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +rkeIngressNginx: + enabled: false + metricsPort: 10254 + component: ingress-nginx + clients: + port: 10015 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + nodeSelector: + node-role.kubernetes.io/worker: "true" + +## k3s PushProx Monitoring +## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox +## +k3sServer: + enabled: false + metricsPort: 10250 + component: k3s-server + clients: + port: 10013 + useLocalhost: true + https: + enabled: true + useServiceAccountCredentials: true + insecureSkipVerify: true + rbac: + additionalRules: + - nonResourceURLs: ["/metrics/cadvisor"] + verbs: ["get"] + - apiGroups: [""] + resources: ["nodes/metrics"] + verbs: ["get"] + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + serviceMonitor: + endpoints: + - port: metrics + honorLabels: true + relabelings: + - sourceLabels: [__metrics_path__] + targetLabel: metrics_path + - port: metrics + path: /metrics/cadvisor + honorLabels: true + relabelings: + - sourceLabels: [__metrics_path__] + targetLabel: metrics_path + - port: metrics + path: /metrics/probes + honorLabels: true + relabelings: + - sourceLabels: [__metrics_path__] + targetLabel: metrics_path + +hardened: + k3s: + networkPolicy: + enabled: true + +## KubeADM PushProx Monitoring +## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox +## +kubeAdmControllerManager: + enabled: false + metricsPort: 10257 + component: kube-controller-manager + clients: + port: 10011 + useLocalhost: true + https: + enabled: true + useServiceAccountCredentials: true + insecureSkipVerify: true + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +kubeAdmScheduler: + enabled: false + metricsPort: 10259 + component: kube-scheduler + clients: + port: 10012 + useLocalhost: true + https: + enabled: true + useServiceAccountCredentials: true + insecureSkipVerify: true + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +kubeAdmProxy: + enabled: false + metricsPort: 10249 + component: kube-proxy + clients: + port: 10013 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +kubeAdmEtcd: + enabled: false + metricsPort: 2381 + component: kube-etcd + clients: + port: 10014 + useLocalhost: true + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +## rke2 PushProx Monitoring +## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox +## +rke2ControllerManager: + enabled: false + metricsPort: 10257 # default to secure port as of k8s >= 1.22 + component: kube-controller-manager + clients: + https: + enabled: true + insecureSkipVerify: true + useServiceAccountCredentials: true + port: 10011 + useLocalhost: true + nodeSelector: + node-role.kubernetes.io/master: "true" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + kubeVersionOverrides: + - constraint: "< 1.22" + values: + metricsPort: 10252 # default to insecure port in k8s < 1.22 + clients: + https: + enabled: false + insecureSkipVerify: false + useServiceAccountCredentials: false + +rke2Scheduler: + enabled: false + metricsPort: 10259 # default to secure port as of k8s >= 1.22 + component: kube-scheduler + clients: + https: + enabled: true + insecureSkipVerify: true + useServiceAccountCredentials: true + port: 10012 + useLocalhost: true + nodeSelector: + node-role.kubernetes.io/master: "true" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + kubeVersionOverrides: + - constraint: "< 1.22" + values: + metricsPort: 10251 # default to insecure port in k8s < 1.22 + clients: + https: + enabled: false + insecureSkipVerify: false + useServiceAccountCredentials: false + +rke2Proxy: + enabled: false + metricsPort: 10249 + component: kube-proxy + clients: + port: 10013 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +rke2Etcd: + enabled: false + metricsPort: 2381 + component: kube-etcd + clients: + port: 10014 + useLocalhost: true + nodeSelector: + node-role.kubernetes.io/etcd: "true" + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +rke2IngressNginx: + enabled: false + metricsPort: 10254 + component: ingress-nginx + networkPolicy: + enabled: false + # in the RKE2 cluster, the ingress-nginx-controller is deployed + # as a non-hostNetwork workload starting at the following versions + # - >= v1.22.12+rke2r1 < 1.23.0-0 + # - >= v1.23.9+rke2r1 < 1.24.0-0 + # - >= v1.24.3+rke2r1 < 1.25.0-0 + # - >= v1.25.0+rke2r1 + # As a result we do not need clients and proxies as we can directly create + # a service that targets the workload with the given app name + namespaceOverride: kube-system + clients: + enabled: false + proxy: + enabled: false + service: + selector: + app.kubernetes.io/name: rke2-ingress-nginx + kubeVersionOverrides: + - constraint: "< 1.21.0-0" + values: + namespaceOverride: "" + clients: + enabled: true + port: 10015 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "app.kubernetes.io/component" + operator: "In" + values: + - "controller" + topologyKey: "kubernetes.io/hostname" + namespaces: + - "kube-system" + # in the RKE2 cluster, the ingress-nginx-controller is deployed as + # a DaemonSet with 1 pod when RKE2 version is < 1.21.0-0 + deployment: + enabled: false + proxy: + enabled: true + service: + selector: false + - constraint: ">= 1.21.0-0 < 1.22.12-0" + values: + namespaceOverride: "" + clients: + enabled: true + port: 10015 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "app.kubernetes.io/component" + operator: "In" + values: + - "controller" + topologyKey: "kubernetes.io/hostname" + namespaces: + - "kube-system" + # in the RKE2 cluster, the ingress-nginx-controller is deployed as + # a hostNetwork Deployment with 1 pod when RKE2 version is >= 1.21.0-0 + deployment: + enabled: true + replicas: 1 + proxy: + enabled: true + service: + selector: false + - constraint: ">= 1.23.0-0 < v1.23.9-0" + values: + namespaceOverride: "" + clients: + enabled: true + port: 10015 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "app.kubernetes.io/component" + operator: "In" + values: + - "controller" + topologyKey: "kubernetes.io/hostname" + namespaces: + - "kube-system" + # in the RKE2 cluster, the ingress-nginx-controller is deployed as + # a hostNetwork Deployment with 1 pod when RKE2 version is >= 1.20.0-0 + deployment: + enabled: true + replicas: 1 + proxy: + enabled: true + service: + selector: false + - constraint: ">= 1.24.0-0 < v1.24.3-0" + values: + namespaceOverride: "" + clients: + enabled: true + port: 10015 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "app.kubernetes.io/component" + operator: "In" + values: + - "controller" + topologyKey: "kubernetes.io/hostname" + namespaces: + - "kube-system" + # in the RKE2 cluster, the ingress-nginx-controller is deployed as + # a hostNetwork Deployment with 1 pod when RKE2 version is >= 1.20.0-0 + deployment: + enabled: true + replicas: 1 + proxy: + enabled: true + service: + selector: false + + + +## Additional PushProx Monitoring +## ref: https://github.com/rancher/charts/tree/dev-v2.9/packages/rancher-monitoring/rancher-pushprox +## + +# hardenedKubelet can only be deployed if kubelet.enabled=true +# If enabled, it replaces the ServiceMonitor deployed by the default kubelet option with a +# PushProx-based exporter that does not require a host port to be open to scrape metrics. +hardenedKubelet: + enabled: false + metricsPort: 10250 + component: kubelet + clients: + port: 10015 + useLocalhost: true + https: + enabled: true + useServiceAccountCredentials: true + insecureSkipVerify: true + rbac: + additionalRules: + - nonResourceURLs: ["/metrics/cadvisor"] + verbs: ["get"] + - apiGroups: [""] + resources: ["nodes/metrics"] + verbs: ["get"] + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + serviceMonitor: + endpoints: + - port: metrics + honorLabels: true + relabelings: + - sourceLabels: [__metrics_path__] + targetLabel: metrics_path + - port: metrics + path: /metrics/cadvisor + honorLabels: true + relabelings: + - sourceLabels: [__metrics_path__] + targetLabel: metrics_path + - port: metrics + path: /metrics/probes + honorLabels: true + relabelings: + - sourceLabels: [__metrics_path__] + targetLabel: metrics_path + +# hardenedNodeExporter can only be deployed if nodeExporter.enabled=true +# If enabled, it replaces the ServiceMonitor deployed by the default nodeExporter with a +# PushProx-based exporter that does not require a host port to be open to scrape metrics. +hardenedNodeExporter: + enabled: false + metricsPort: 9796 + component: node-exporter + clients: + port: 10016 + useLocalhost: true + tolerations: + - effect: "NoExecute" + operator: "Exists" + - effect: "NoSchedule" + operator: "Exists" + +## Upgrades +upgrade: + ## Run upgrade scripts before an upgrade or rollback via a Job hook + enabled: true + ## Image to use to run the scripts + image: + repository: rancher/shell + tag: v0.2.1 + +## Rancher Monitoring +## + +rancherMonitoring: + enabled: true + + ## A namespaceSelector to identify the namespace to find the Rancher deployment + ## + namespaceSelector: + matchNames: + - cattle-system + + ## A selector to identify the Rancher deployment + ## If not set, the chart will try to search for the Rancher deployment in the cattle-system namespace and infer the selector values from it + ## If the Rancher deployment does not exist, no resources will be deployed. + ## + selector: {} + +## Component scraping nginx-ingress-controller +## +ingressNginx: + enabled: false + + ## The namespace to search for your nginx-ingress-controller + ## + namespace: ingress-nginx + + service: + port: 9913 + targetPort: 10254 + # selector: + # app: ingress-nginx + serviceMonitor: + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "30s" + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## metric relabel configs to apply to samples before ingestion. + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + # relabel configs to apply to samples before ingestion. + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + +# Prometheus Operator Configuration + +## Provide a name in place of kube-prometheus-stack for `app:` labels +## NOTE: If you change this value, you must update the prometheus-adapter.prometheus.url +## +nameOverride: "rancher-monitoring" + +## Override the deployment namespace +## NOTE: If you change this value, you must update the prometheus-adapter.prometheus.url +## +namespaceOverride: "cattle-monitoring-system" + +## Provide a k8s version to auto dashboard import script example: kubeTargetVersionOverride: 1.26.6 +## +kubeTargetVersionOverride: "" + +## Allow kubeVersion to be overridden while creating the ingress +## +kubeVersionOverride: "" + +## Provide a name to substitute for the full names of resources +## +fullnameOverride: "" + +## Labels to apply to all resources +## +commonLabels: {} +# scmhash: abc123 +# myLabel: aakkmd + +## Install Prometheus Operator CRDs +## +crds: + enabled: true + +## custom Rules to override "for" and "severity" in defaultRules +## +customRules: {} + # AlertmanagerFailedReload: + # for: 3m + # AlertmanagerMembersInconsistent: + # for: 5m + # severity: "warning" + +## Create default rules for monitoring the cluster +## +defaultRules: + create: true + rules: + alertmanager: true + etcd: true + configReloaders: true + general: true + k8sContainerCpuUsageSecondsTotal: true + k8sContainerMemoryCache: true + k8sContainerMemoryRss: true + k8sContainerMemorySwap: true + k8sContainerResource: true + k8sContainerMemoryWorkingSetBytes: true + k8sPodOwner: true + kubeApiserverAvailability: true + kubeApiserverBurnrate: true + kubeApiserverHistogram: true + kubeApiserverSlos: true + kubeControllerManager: true + kubelet: true + kubeProxy: true + kubePrometheusGeneral: true + kubePrometheusNodeRecording: true + kubernetesApps: true + kubernetesResources: true + kubernetesStorage: true + kubernetesSystem: true + kubeSchedulerAlerting: true + kubeSchedulerRecording: true + kubeStateMetrics: true + network: true + node: true + nodeExporterAlerting: true + nodeExporterRecording: true + prometheus: true + prometheusOperator: true + windows: true + + ## Reduce app namespace alert scope + appNamespacesTarget: ".*" + + ## Set keep_firing_for for all alerts + keepFiringFor: "" + + ## Labels for default rules + labels: {} + ## Annotations for default rules + annotations: {} + + ## Additional labels for PrometheusRule alerts + additionalRuleLabels: {} + + ## Additional annotations for PrometheusRule alerts + additionalRuleAnnotations: {} + + ## Additional labels for specific PrometheusRule alert groups + additionalRuleGroupLabels: + alertmanager: {} + etcd: {} + configReloaders: {} + general: {} + k8sContainerCpuUsageSecondsTotal: {} + k8sContainerMemoryCache: {} + k8sContainerMemoryRss: {} + k8sContainerMemorySwap: {} + k8sContainerResource: {} + k8sPodOwner: {} + kubeApiserverAvailability: {} + kubeApiserverBurnrate: {} + kubeApiserverHistogram: {} + kubeApiserverSlos: {} + kubeControllerManager: {} + kubelet: {} + kubeProxy: {} + kubePrometheusGeneral: {} + kubePrometheusNodeRecording: {} + kubernetesApps: {} + kubernetesResources: {} + kubernetesStorage: {} + kubernetesSystem: {} + kubeSchedulerAlerting: {} + kubeSchedulerRecording: {} + kubeStateMetrics: {} + network: {} + node: {} + nodeExporterAlerting: {} + nodeExporterRecording: {} + prometheus: {} + prometheusOperator: {} + + ## Additional annotations for specific PrometheusRule alerts groups + additionalRuleGroupAnnotations: + alertmanager: {} + etcd: {} + configReloaders: {} + general: {} + k8sContainerCpuUsageSecondsTotal: {} + k8sContainerMemoryCache: {} + k8sContainerMemoryRss: {} + k8sContainerMemorySwap: {} + k8sContainerResource: {} + k8sPodOwner: {} + kubeApiserverAvailability: {} + kubeApiserverBurnrate: {} + kubeApiserverHistogram: {} + kubeApiserverSlos: {} + kubeControllerManager: {} + kubelet: {} + kubeProxy: {} + kubePrometheusGeneral: {} + kubePrometheusNodeRecording: {} + kubernetesApps: {} + kubernetesResources: {} + kubernetesStorage: {} + kubernetesSystem: {} + kubeSchedulerAlerting: {} + kubeSchedulerRecording: {} + kubeStateMetrics: {} + network: {} + node: {} + nodeExporterAlerting: {} + nodeExporterRecording: {} + prometheus: {} + prometheusOperator: {} + + additionalAggregationLabels: [] + + ## Prefix for runbook URLs. Use this to override the first part of the runbookURLs that is common to all rules. + runbookUrl: "https://runbooks.prometheus-operator.dev/runbooks" + + ## Disabled PrometheusRule alerts + disabled: {} + # KubeAPIDown: true + # NodeRAIDDegraded: true + +## Deprecated way to provide custom recording or alerting rules to be deployed into the cluster. +## +# additionalPrometheusRules: [] +# - name: my-rule-file +# groups: +# - name: my_group +# rules: +# - record: my_record +# expr: 100 * my_record + +## Provide custom recording or alerting rules to be deployed into the cluster. +## +additionalPrometheusRulesMap: {} +# rule-name: +# groups: +# - name: my_group +# rules: +# - record: my_record +# expr: 100 * my_record + +## +global: + cattle: + + systemDefaultRegistry: "" + ## Windows Monitoring + ## ref: https://github.com/rancher/charts/tree/dev-v2.5-source/packages/rancher-windows-exporter + ## + ## Deploys a DaemonSet of Prometheus exporters based on https://github.com/prometheus-community/windows_exporter. + ## Every Windows host must have a wins version of 0.1.0+ to use this chart (default as of Rancher 2.5.8). + ## To upgrade wins versions on Windows hosts, see https://github.com/rancher/wins/tree/master/charts/rancher-wins-upgrader. + ## + windows: + enabled: false + seLinux: + enabled: false + kubectl: + repository: rancher/kubectl + tag: v1.20.2 + pullPolicy: IfNotPresent + rbac: + ## Create RBAC resources for ServiceAccounts and users + ## + create: true + + userRoles: + ## Create default user ClusterRoles to allow users to interact with Prometheus CRs, ConfigMaps, and Secrets + create: true + ## Aggregate default user ClusterRoles into default k8s ClusterRoles + aggregateToDefaultRoles: true + + ## Create ClusterRoles that extend the existing view, edit and admin ClusterRoles to interact with prometheus-operator CRDs + ## Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles + createAggregateClusterRoles: false + + pspAnnotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + ## Global image registry to use if it needs to be overriden for some specific use cases (e.g local registries, custom images, ...) + ## + imageRegistry: "docker.io" + + ## Reference to one or more secrets to be used when pulling images + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + imagePullSecrets: [] + # - name: "image-pull-secret" + # or + # - "image-pull-secret" + +windowsMonitoring: + ## Deploys the windows-exporter and Windows-specific dashboards and rules (job name must be 'windows-exporter') + enabled: false + +loggingMonitors: + ## Deploys logging-specific dashboards, make sure to also set metrics.serviceMonitor to true in the logging chart for both fluentd and fluentbit + fluentd: + enabled: false + fluentbit: + enabled: false + +## Configuration for prometheus-windows-exporter +## ref: https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-windows-exporter +## +prometheus-windows-exporter: + ## Enable ServiceMonitor and set Kubernetes label to use as a job label + ## + prometheus: + monitor: + enabled: true + jobLabel: jobLabel + + releaseLabel: true + + ## Set job label to 'windows-exporter' as required by the default Prometheus rules and Grafana dashboards + ## + podLabels: + jobLabel: windows-exporter + + ## Enable memory and container metrics as required by the default Prometheus rules and Grafana dashboards + ## + config: |- + collectors: + enabled: '[defaults],memory,container' + +## Configuration for alertmanager +## ref: https://prometheus.io/docs/alerting/alertmanager/ +## +alertmanager: + + ## Deploy alertmanager + ## + enabled: true + + ## Annotations for Alertmanager + ## + annotations: {} + + ## Api that prometheus will use to communicate with alertmanager. Possible values are v1, v2 + ## + apiVersion: v2 + + ## @param alertmanager.enableFeatures Enable access to Alertmanager disabled features. + ## + enableFeatures: [] + + ## Service account for Alertmanager to use. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ## + serviceAccount: + create: true + name: "" + annotations: {} + automountServiceAccountToken: true + + ## Configure pod disruption budgets for Alertmanager + ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget + ## + podDisruptionBudget: + enabled: false + minAvailable: 1 + maxUnavailable: "" + + ## Alertmanager configuration directives + ## ref: https://prometheus.io/docs/alerting/configuration/#configuration-file + ## https://prometheus.io/webtools/alerting/routing-tree-editor/ + ## + config: + global: + resolve_timeout: 5m + inhibit_rules: + - source_matchers: + - 'severity = critical' + target_matchers: + - 'severity =~ warning|info' + equal: + - 'namespace' + - 'alertname' + - source_matchers: + - 'severity = warning' + target_matchers: + - 'severity = info' + equal: + - 'namespace' + - 'alertname' + - source_matchers: + - 'alertname = InfoInhibitor' + target_matchers: + - 'severity = info' + equal: + - 'namespace' + - target_matchers: + - 'alertname = InfoInhibitor' + route: + group_by: ['namespace'] + group_wait: 30s + group_interval: 5m + repeat_interval: 12h + receiver: 'null' + routes: + - receiver: 'null' + matchers: + - alertname = "Watchdog" + receivers: + - name: 'null' + templates: + - '/etc/alertmanager/config/*.tmpl' + + ## Alertmanager configuration directives (as string type, preferred over the config hash map) + ## stringConfig will be used only, if tplConfig is true + ## ref: https://prometheus.io/docs/alerting/configuration/#configuration-file + ## https://prometheus.io/webtools/alerting/routing-tree-editor/ + ## + stringConfig: "" + + ## Pass the Alertmanager configuration directives through Helm's templating + ## engine. If the Alertmanager configuration contains Alertmanager templates, + ## they'll need to be properly escaped so that they are not interpreted by + ## Helm + ## ref: https://helm.sh/docs/developing_charts/#using-the-tpl-function + ## https://prometheus.io/docs/alerting/configuration/#tmpl_string + ## https://prometheus.io/docs/alerting/notifications/ + ## https://prometheus.io/docs/alerting/notification_examples/ + tplConfig: false + + ## Alertmanager template files to format alerts + ## By default, templateFiles are placed in /etc/alertmanager/config/ and if + ## they have a .tmpl file suffix will be loaded. See config.templates above + ## to change, add other suffixes. If adding other suffixes, be sure to update + ## config.templates above to include those suffixes. + ## ref: https://prometheus.io/docs/alerting/notifications/ + ## https://prometheus.io/docs/alerting/notification_examples/ + ## + templateFiles: + rancher_defaults.tmpl: |- + {{- define "slack.rancher.text" -}} + {{ template "rancher.text_multiple" . }} + {{- end -}} + + {{- define "rancher.text_multiple" -}} + *[GROUP - Details]* + One or more alarms in this group have triggered a notification. + + {{- if gt (len .GroupLabels.Values) 0 }} + *Group Labels:* + {{- range .GroupLabels.SortedPairs }} + • *{{ .Name }}:* `{{ .Value }}` + {{- end }} + {{- end }} + {{- if .ExternalURL }} + *Link to AlertManager:* {{ .ExternalURL }} + {{- end }} + + {{- range .Alerts }} + {{ template "rancher.text_single" . }} + {{- end }} + {{- end -}} + + {{- define "rancher.text_single" -}} + {{- if .Labels.alertname }} + *[ALERT - {{ .Labels.alertname }}]* + {{- else }} + *[ALERT]* + {{- end }} + {{- if .Labels.severity }} + *Severity:* `{{ .Labels.severity }}` + {{- end }} + {{- if .Labels.cluster }} + *Cluster:* {{ .Labels.cluster }} + {{- end }} + {{- if .Annotations.summary }} + *Summary:* {{ .Annotations.summary }} + {{- end }} + {{- if .Annotations.message }} + *Message:* {{ .Annotations.message }} + {{- end }} + {{- if .Annotations.description }} + *Description:* {{ .Annotations.description }} + {{- end }} + {{- if .Annotations.runbook_url }} + *Runbook URL:* <{{ .Annotations.runbook_url }}|:spiral_note_pad:> + {{- end }} + {{- with .Labels }} + {{- with .Remove (stringSlice "alertname" "severity" "cluster") }} + {{- if gt (len .) 0 }} + *Additional Labels:* + {{- range .SortedPairs }} + • *{{ .Name }}:* `{{ .Value }}` + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Annotations }} + {{- with .Remove (stringSlice "summary" "message" "description" "runbook_url") }} + {{- if gt (len .) 0 }} + *Additional Annotations:* + {{- range .SortedPairs }} + • *{{ .Name }}:* `{{ .Value }}` + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- end -}} + + ingress: + 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 + + annotations: {} + + labels: {} + + ## Override ingress to a different defined port on the service + # servicePort: 8081 + ## Override ingress to a different service then the default, this is useful if you need to + ## point to a specific instance of the alertmanager (eg kube-prometheus-stack-alertmanager-0) + # serviceName: kube-prometheus-stack-alertmanager-0 + + ## Hosts must be provided if Ingress is enabled. + ## + hosts: [] + # - alertmanager.domain.com + + ## Paths to use for ingress rules - one path should match the alertmanagerSpec.routePrefix + ## + paths: [] + # - / + + ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) + ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types + # pathType: ImplementationSpecific + + ## TLS configuration for Alertmanager Ingress + ## Secret must be manually created in the namespace + ## + tls: [] + # - secretName: alertmanager-general-tls + # hosts: + # - alertmanager.example.com + + ## Configuration for Alertmanager secret + ## + secret: + annotations: {} + + # by default the alertmanager secret is not overwritten if it already exists + recreateIfExists: false + + ## Configuration for creating an Ingress that will map to each Alertmanager replica service + ## alertmanager.servicePerReplica must be enabled + ## + ingressPerReplica: + 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 + + annotations: {} + labels: {} + + ## Final form of the hostname for each per replica ingress is + ## {{ ingressPerReplica.hostPrefix }}-{{ $replicaNumber }}.{{ ingressPerReplica.hostDomain }} + ## + ## Prefix for the per replica ingress that will have `-$replicaNumber` + ## appended to the end + hostPrefix: "" + ## Domain that will be used for the per replica ingress + hostDomain: "" + + ## Paths to use for ingress rules + ## + paths: [] + # - / + + ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) + ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types + # pathType: ImplementationSpecific + + ## Secret name containing the TLS certificate for alertmanager per replica ingress + ## Secret must be manually created in the namespace + tlsSecretName: "" + + ## Separated secret for each per replica Ingress. Can be used together with cert-manager + ## + tlsSecretPerReplica: + enabled: false + ## Final form of the secret for each per replica ingress is + ## {{ tlsSecretPerReplica.prefix }}-{{ $replicaNumber }} + ## + prefix: "alertmanager" + + ## Configuration for Alertmanager service + ## + service: + annotations: {} + labels: {} + clusterIP: "" + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + + ## Port for Alertmanager Service to listen on + ## + port: 9093 + ## To be used with a proxy extraContainer port + ## + targetPort: 9093 + ## Port to expose on each node + ## Only used if service.type is 'NodePort' + ## + nodePort: 30903 + ## List of IP addresses at which the Prometheus server service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + + ## Additional ports to open for Alertmanager service + ## + additionalPorts: [] + # - name: oauth-proxy + # port: 8081 + # targetPort: 8081 + # - name: oauth-metrics + # port: 8082 + # targetPort: 8082 + + externalIPs: [] + loadBalancerIP: "" + loadBalancerSourceRanges: [] + + ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + ## + externalTrafficPolicy: Cluster + + ## If you want to make sure that connections from a particular client are passed to the same Pod each time + ## Accepts 'ClientIP' or 'None' + ## + sessionAffinity: None + + ## If you want to modify the ClientIP sessionAffinity timeout + ## The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP" + ## + sessionAffinityConfig: + clientIP: + timeoutSeconds: 10800 + + ## Service type + ## + type: ClusterIP + + ## Configuration for creating a separate Service for each statefulset Alertmanager replica + ## + servicePerReplica: + enabled: false + annotations: {} + + ## Port for Alertmanager Service per replica to listen on + ## + port: 9093 + + ## To be used with a proxy extraContainer port + targetPort: 9093 + + ## Port to expose on each node + ## Only used if servicePerReplica.type is 'NodePort' + ## + nodePort: 30904 + + ## Loadbalancer source IP ranges + ## Only used if servicePerReplica.type is "LoadBalancer" + loadBalancerSourceRanges: [] + + ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + ## + externalTrafficPolicy: Cluster + + ## Service type + ## + type: ClusterIP + + ## Configuration for creating a ServiceMonitor for AlertManager + ## + serviceMonitor: + ## If true, a ServiceMonitor will be created for the AlertManager service. + ## + selfMonitor: true + + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## Additional labels + ## + additionalLabels: {} + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS. + scheme: "" + + ## enableHttp2: Whether to enable HTTP2. + ## See https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#endpoint + enableHttp2: true + + ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS. + ## Of type: https://github.com/coreos/prometheus-operator/blob/main/Documentation/api.md#tlsconfig + tlsConfig: {} + + bearerTokenFile: + + ## 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__] + + ## 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 + + ## Additional Endpoints + ## + additionalEndpoints: [] + # - port: oauth-metrics + # path: /metrics + + ## Settings affecting alertmanagerSpec + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#alertmanagerspec + ## + alertmanagerSpec: + ## Standard object's metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata + ## Metadata Labels and Annotations gets propagated to the Alertmanager pods. + ## + podMetadata: {} + + ## Image of Alertmanager + ## + image: + repository: rancher/mirrored-prometheus-alertmanager + tag: v0.27.0 + sha: "" + + ## If true then the user will be responsible to provide a secret with alertmanager configuration + ## So when true the config part will be ignored (including templateFiles) and the one in the secret will be used + ## + useExistingSecret: false + + ## Secrets is a list of Secrets in the same namespace as the Alertmanager object, which shall be mounted into the + ## Alertmanager Pods. The Secrets are mounted into /etc/alertmanager/secrets/. + ## + secrets: [] + + ## If false then the user will opt out of automounting API credentials. + ## + automountServiceAccountToken: true + + ## ConfigMaps is a list of ConfigMaps in the same namespace as the Alertmanager object, which shall be mounted into the Alertmanager Pods. + ## The ConfigMaps are mounted into /etc/alertmanager/configmaps/. + ## + configMaps: [] + + ## ConfigSecret is the name of a Kubernetes Secret in the same namespace as the Alertmanager object, which contains configuration for + ## this Alertmanager instance. Defaults to 'alertmanager-' The secret is mounted into /etc/alertmanager/config. + ## + # configSecret: + + ## WebTLSConfig defines the TLS parameters for HTTPS + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#alertmanagerwebspec + web: {} + + ## AlertmanagerConfigs to be selected to merge and configure Alertmanager with. + ## + alertmanagerConfigSelector: {} + ## Example which selects all alertmanagerConfig resources + ## with label "alertconfig" with values any of "example-config" or "example-config-2" + # alertmanagerConfigSelector: + # matchExpressions: + # - key: alertconfig + # operator: In + # values: + # - example-config + # - example-config-2 + # + ## Example which selects all alertmanagerConfig resources with label "role" set to "example-config" + # alertmanagerConfigSelector: + # matchLabels: + # role: example-config + + ## Namespaces to be selected for AlertmanagerConfig discovery. If nil, only check own namespace. + ## + alertmanagerConfigNamespaceSelector: {} + ## Example which selects all namespaces + ## with label "alertmanagerconfig" with values any of "example-namespace" or "example-namespace-2" + # alertmanagerConfigNamespaceSelector: + # matchExpressions: + # - key: alertmanagerconfig + # operator: In + # values: + # - example-namespace + # - example-namespace-2 + + ## Example which selects all namespaces with label "alertmanagerconfig" set to "enabled" + # alertmanagerConfigNamespaceSelector: + # matchLabels: + # alertmanagerconfig: enabled + + ## AlermanagerConfig to be used as top level configuration + ## + alertmanagerConfiguration: {} + ## Example with select a global alertmanagerconfig + # alertmanagerConfiguration: + # name: global-alertmanager-Configuration + + ## Defines the strategy used by AlertmanagerConfig objects to match alerts. eg: + ## + alertmanagerConfigMatcherStrategy: {} + ## Example with use OnNamespace strategy + # alertmanagerConfigMatcherStrategy: + # type: OnNamespace + + ## Define Log Format + # Use logfmt (default) or json logging + logFormat: logfmt + + ## Log level for Alertmanager to be configured with. + ## + logLevel: info + + ## Size is the expected size of the alertmanager cluster. The controller will eventually make the size of the + ## running cluster equal to the expected size. + replicas: 1 + + ## Time duration Alertmanager shall retain data for. Default is '120h', and must match the regular expression + ## [0-9]+(ms|s|m|h) (milliseconds seconds minutes hours). + ## + retention: 120h + + ## Storage is the definition of how storage will be used by the Alertmanager instances. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/storage.md + ## + storage: {} + # volumeClaimTemplate: + # spec: + # storageClassName: gluster + # accessModes: ["ReadWriteOnce"] + # resources: + # requests: + # storage: 50Gi + # selector: {} + + + ## The external URL the Alertmanager instances will be available under. This is necessary to generate correct URLs. This is necessary if Alertmanager is not served from root of a DNS name. string false + ## + externalUrl: + + ## The route prefix Alertmanager registers HTTP handlers for. This is useful, if using ExternalURL and a proxy is rewriting HTTP routes of a request, and the actual ExternalURL is still true, + ## but the server serves requests under a different route prefix. For example for use with kubectl proxy. + ## + routePrefix: / + + ## scheme: HTTP scheme to use. Can be used with `tlsConfig` for example if using istio mTLS. + scheme: "" + + ## tlsConfig: TLS configuration to use when connect to the endpoint. For example if using istio mTLS. + ## Of type: https://github.com/coreos/prometheus-operator/blob/main/Documentation/api.md#tlsconfig + tlsConfig: {} + + ## If set to true all actions on the underlying managed objects are not going to be performed, except for delete actions. + ## + paused: false + + ## Define which Nodes the Pods are scheduled on. + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Define resources requests and limits for single Pods. + ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: + limits: + memory: 500Mi + cpu: 1000m + requests: + memory: 100Mi + cpu: 100m + + ## Pod anti-affinity can prevent the scheduler from placing Prometheus replicas on the same node. + ## The default value "soft" means that the scheduler should *prefer* to not schedule two replica pods onto the same node but no guarantee is provided. + ## The value "hard" means that the scheduler is *required* to not schedule two replica pods onto the same node. + ## The value "" will disable pod anti-affinity so that no anti-affinity rules will be configured. + ## + podAntiAffinity: "" + + ## If anti-affinity is enabled sets the topologyKey to use for anti-affinity. + ## This can be changed to, for example, failure-domain.beta.kubernetes.io/zone + ## + podAntiAffinityTopologyKey: kubernetes.io/hostname + + ## Assign custom affinity rules to the alertmanager instance + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + affinity: {} + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/e2e-az-name + # operator: In + # values: + # - e2e-az1 + # - e2e-az2 + + ## If specified, the pod's tolerations. + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal" + # value: "value" + # effect: "NoSchedule" + + ## If specified, the pod's topology spread constraints. + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app: alertmanager + + ## SecurityContext holds pod-level security attributes and common container settings. + ## This defaults to non root user with uid 1000 and gid 2000. *v1.PodSecurityContext false + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## + securityContext: + runAsGroup: 2000 + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 2000 + seccompProfile: + type: RuntimeDefault + + ## ListenLocal makes the Alertmanager server listen on loopback, so that it does not bind against the Pod IP. + ## Note this is only for the Alertmanager UI, not the gossip communication. + ## + listenLocal: false + + ## Containers allows injecting additional containers. This is meant to allow adding an authentication proxy to an Alertmanager pod. + ## + containers: [] + # containers: + # - name: oauth-proxy + # image: quay.io/oauth2-proxy/oauth2-proxy:v7.5.1 + # args: + # - --upstream=http://127.0.0.1:9093 + # - --http-address=0.0.0.0:8081 + # - --metrics-address=0.0.0.0:8082 + # - ... + # ports: + # - containerPort: 8081 + # name: oauth-proxy + # protocol: TCP + # - containerPort: 8082 + # name: oauth-metrics + # protocol: TCP + # resources: {} + + # Additional volumes on the output StatefulSet definition. + volumes: [] + + # Additional VolumeMounts on the output StatefulSet definition. + volumeMounts: [] + + ## InitContainers allows injecting additional initContainers. This is meant to allow doing some changes + ## (permissions, dir tree) on mounted volumes before starting prometheus + initContainers: [] + + ## Priority class assigned to the Pods + ## + priorityClassName: "" + + ## AdditionalPeers allows injecting a set of additional Alertmanagers to peer with to form a highly available cluster. + ## + additionalPeers: [] + + ## PortName to use for Alert Manager. + ## + portName: "http-web" + + ## ClusterAdvertiseAddress is the explicit address to advertise in cluster. Needs to be provided for non RFC1918 [1] (public) addresses. [1] RFC1918: https://tools.ietf.org/html/rfc1918 + ## + clusterAdvertiseAddress: false + + ## clusterGossipInterval determines interval between gossip attempts. + ## Needs to be specified as GoDuration, a time duration that can be parsed by Go’s time.ParseDuration() (e.g. 45ms, 30s, 1m, 1h20m15s) + clusterGossipInterval: "" + + ## clusterPeerTimeout determines timeout for cluster peering. + ## Needs to be specified as GoDuration, a time duration that can be parsed by Go’s time.ParseDuration() (e.g. 45ms, 30s, 1m, 1h20m15s) + clusterPeerTimeout: "" + + ## clusterPushpullInterval determines interval between pushpull attempts. + ## Needs to be specified as GoDuration, a time duration that can be parsed by Go’s time.ParseDuration() (e.g. 45ms, 30s, 1m, 1h20m15s) + clusterPushpullInterval: "" + + ## ForceEnableClusterMode ensures Alertmanager does not deactivate the cluster mode when running with a single replica. + ## Use case is e.g. spanning an Alertmanager cluster across Kubernetes clusters with a single replica in each. + forceEnableClusterMode: false + + ## Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to + ## be considered available. Defaults to 0 (pod will be considered available as soon as it is ready). + minReadySeconds: 0 + + ## Additional configuration which is not covered by the properties above. (passed through tpl) + additionalConfig: {} + + ## Additional configuration which is not covered by the properties above. + ## Useful, if you need advanced templating inside alertmanagerSpec. + ## Otherwise, use alertmanager.alertmanagerSpec.additionalConfig (passed through tpl) + additionalConfigString: "" + + ## ExtraSecret can be used to store various data in an extra secret + ## (use it for example to store hashed basic auth credentials) + extraSecret: + ## if not set, name will be auto generated + # name: "" + annotations: {} + data: {} + # auth: | + # foo:$apr1$OFG3Xybp$ckL0FHDAkoXYIlH9.cysT0 + # someoneelse:$apr1$DMZX2Z4q$6SbQIfyuLQd.xmo/P0m2c. + +## Using default values from https://github.com/grafana/helm-charts/blob/main/charts/grafana/values.yaml +## +grafana: + enabled: true + namespaceOverride: "" + + ## Grafana's primary configuration + ## NOTE: values in map will be converted to ini format + ## ref: http://docs.grafana.org/installation/configuration/ + ## + grafana.ini: + users: + auto_assign_org_role: Viewer + auth: + disable_login_form: false + auth.anonymous: + enabled: true + org_role: Viewer + auth.basic: + enabled: false + dashboards: + # Modify this value to change the default dashboard shown on the main Grafana page + default_home_dashboard_path: /tmp/dashboards/rancher-default-home.json + security: + # Required to embed dashboards in Rancher Cluster Overview Dashboard on Cluster Explorer + allow_embedding: true + + deploymentStrategy: + type: Recreate + + ## ForceDeployDatasources Create datasource configmap even if grafana deployment has been disabled + ## + forceDeployDatasources: false + + ## ForceDeployDashboard Create dashboard configmap even if grafana deployment has been disabled + ## + forceDeployDashboards: false + + ## Deploy default dashboards + ## + defaultDashboardsEnabled: true + + # Additional options for defaultDashboards + defaultDashboards: + # The default namespace to place defaultDashboards within + namespace: cattle-dashboards + # Whether to create the default namespace as a Helm managed namespace or use an existing namespace + # If false, the defaultDashboards.namespace will be created as a Helm managed namespace + useExistingNamespace: false + # Whether the Helm managed namespace created by this chart should be left behind on a Helm uninstall + # If you place other dashboards in this namespace, then they will be deleted on a helm uninstall + # Ignore if useExistingNamespace is true + cleanupOnUninstall: false + + ## Timezone for the default dashboards + ## Other options are: browser or a specific timezone, i.e. Europe/Luxembourg + ## + defaultDashboardsTimezone: utc + + ## Editable flag for the default dashboards + ## + defaultDashboardsEditable: true + + adminPassword: prom-operator + + rbac: + ## If true, Grafana PSPs will be created + ## + pspEnabled: false + + ingress: + ## If true, Grafana Ingress will be created + ## + enabled: false + + ## IngressClassName for Grafana Ingress. + ## Should be provided if Ingress is enable. + ## + # ingressClassName: nginx + + ## Annotations for Grafana Ingress + ## + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + + ## Labels to be added to the Ingress + ## + labels: {} + + ## Hostnames. + ## Must be provided if Ingress is enable. + ## + # hosts: + # - grafana.domain.com + hosts: [] + + ## Path for grafana ingress + path: / + + ## TLS configuration for grafana Ingress + ## Secret must be manually created in the namespace + ## + tls: [] + # - secretName: grafana-general-tls + # hosts: + # - grafana.example.com + + # # To make Grafana persistent (Using Statefulset) + # # + # persistence: + # enabled: true + # type: sts + # storageClassName: "storageClassName" + # accessModes: + # - ReadWriteOnce + # size: 20Gi + # finalizers: + # - kubernetes.io/pvc-protection + + serviceAccount: + create: true + autoMount: true + + sidecar: + dashboards: + enabled: true + label: grafana_dashboard + searchNamespace: cattle-dashboards + labelValue: "1" + + # Support for new table panels, when enabled grafana auto migrates the old table panels to newer table panels + enableNewTablePanelSyntax: false + + ## Annotations for Grafana dashboard configmaps + ## + annotations: {} + multicluster: + global: + enabled: false + etcd: + enabled: false + provider: + allowUiUpdates: false + datasources: + enabled: true + defaultDatasourceEnabled: true + isDefaultDatasource: true + + name: Prometheus + uid: prometheus + + ## URL of prometheus datasource + ## + # url: http://prometheus-stack-prometheus:9090/ + + ## Prometheus request timeout in seconds + # timeout: 30 + + # If not defined, will use prometheus.prometheusSpec.scrapeInterval or its default + # defaultDatasourceScrapeInterval: 15s + + ## Annotations for Grafana datasource configmaps + ## + annotations: {} + + ## Set method for HTTP to send query to datasource + httpMethod: POST + + ## Create datasource for each Pod of Prometheus StatefulSet; + ## this uses headless service `prometheus-operated` which is + ## created by Prometheus Operator + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/0fee93e12dc7c2ea1218f19ae25ec6b893460590/pkg/prometheus/statefulset.go#L255-L286 + createPrometheusReplicasDatasources: false + label: grafana_datasource + labelValue: "1" + + ## Field with internal link pointing to existing data source in Grafana. + ## Can be provisioned via additionalDataSources + exemplarTraceIdDestinations: {} + # datasourceUid: Jaeger + # traceIdLabelName: trace_id + alertmanager: + enabled: true + name: Alertmanager + uid: alertmanager + handleGrafanaManagedAlerts: false + implementation: prometheus + + extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /etc/grafana/ssl/ + # configMap: certs-configmap + # readOnly: true + + deleteDatasources: [] + # - name: example-datasource + # orgId: 1 + + ## Configure additional grafana datasources (passed through tpl) + ## ref: http://docs.grafana.org/administration/provisioning/#datasources + additionalDataSources: [] + # - name: prometheus-sample + # access: proxy + # basicAuth: true + # basicAuthPassword: pass + # basicAuthUser: daco + # editable: false + # jsonData: + # tlsSkipVerify: true + # orgId: 1 + # type: prometheus + # url: https://{{ printf "%s-prometheus.svc" .Release.Name }}:9090 + # version: 1 + + ## Passed to grafana subchart and used by servicemonitor below + ## + service: + portName: nginx-http + ## Port for Grafana Service to listen on + ## + port: 80 + ## To be used with a proxy extraContainer port + ## + targetPort: 8080 + ## Port to expose on each node + ## Only used if service.type is 'NodePort' + ## + nodePort: 30950 + ## Service type + ## + type: ClusterIP + + ipFamilies: [] + ipFamilyPolicy: "" + + proxy: + image: + repository: rancher/mirrored-library-nginx + tag: 1.24.0-alpine + + ## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod + extraContainers: | + - name: grafana-proxy + args: + - nginx + - -g + - daemon off; + - -c + - /nginx/nginx.conf + image: "{{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }}" + ports: + - containerPort: 8080 + name: nginx-http + protocol: TCP + volumeMounts: + - mountPath: /nginx + name: grafana-nginx + - mountPath: /var/cache/nginx + name: nginx-home + securityContext: + runAsUser: 101 + runAsGroup: 101 + + ## Volumes that can be used in containers + extraContainerVolumes: + - name: nginx-home + emptyDir: {} + - name: grafana-nginx + configMap: + name: grafana-nginx-proxy-config + items: + - key: nginx.conf + mode: 438 + path: nginx.conf + + ## If true, create a serviceMonitor for grafana + ## + serviceMonitor: + # If true, a ServiceMonitor CRD is created for a prometheus operator + # https://github.com/coreos/prometheus-operator + # + enabled: true + + # Path to use for scraping metrics. Might be different if server.root_url is set + # in grafana.ini + path: "/metrics" + + # namespace: monitoring (defaults to use the namespace this chart is deployed to) + + # labels for the ServiceMonitor + labels: {} + + # Scrape interval. If not set, the Prometheus default scrape interval is used. + # + interval: "" + scheme: http + tlsConfig: {} + scrapeTimeout: 30s + + ## 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 + + resources: + limits: + memory: 200Mi + cpu: 200m + requests: + memory: 100Mi + cpu: 100m + + testFramework: + enabled: false + +## Flag to disable all the kubernetes component scrapers +## +kubernetesServiceMonitors: + enabled: true + +## Component scraping the kube api server +## +kubeApiServer: + enabled: true + tlsConfig: + serverName: kubernetes + insecureSkipVerify: false + serviceMonitor: + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + jobLabel: component + selector: + matchLabels: + component: apiserver + provider: kubernetes + + ## 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: + # Drop excessively noisy apiserver buckets. + - action: drop + regex: apiserver_request_duration_seconds_bucket;(0.15|0.2|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2|3|3.5|4|4.5|6|7|8|9|15|25|40|50) + sourceLabels: + - __name__ + - le + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## 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_namespace + # - __meta_kubernetes_service_name + # - __meta_kubernetes_endpoint_port_name + # action: keep + # regex: default;kubernetes;https + # - targetLabel: __address__ + # replacement: kubernetes.default.svc:443 + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping the kubelet and kubelet-hosted cAdvisor +## +kubelet: + enabled: true + namespace: kube-system + + serviceMonitor: + ## Attach metadata to discovered targets. Requires Prometheus v2.45 for endpoints created by the operator. + ## + attachMetadata: + node: false + + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## If true, Prometheus use (respect) labels provided by exporter. + ## + honorLabels: true + + ## If true, Prometheus ingests metrics with timestamp provided by exporter. If false, Prometheus ingests metrics with timestamp of scrape. + ## + honorTimestamps: true + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## Enable scraping the kubelet over https. For requirements to enable this see + ## https://github.com/prometheus-operator/prometheus-operator/issues/926 + ## + https: true + + ## Skip TLS certificate validation when scraping. + ## This is enabled by default because kubelet serving certificate deployed by kubeadm is by default self-signed + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#kubelet-serving-certs + ## + insecureSkipVerify: true + + ## Enable scraping /metrics/cadvisor from kubelet's service + ## + cAdvisor: true + + ## Enable scraping /metrics/probes from kubelet's service + ## + probes: true + + ## Enable scraping /metrics/resource from kubelet's service + ## This is disabled by default because container metrics are already exposed by cAdvisor + ## + resource: false + # From kubernetes 1.18, /metrics/resource/v1alpha1 renamed to /metrics/resource + resourcePath: "/metrics/resource/v1alpha1" + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + cAdvisorMetricRelabelings: + # Drop less useful container CPU metrics. + - sourceLabels: [__name__] + action: drop + regex: 'container_cpu_(cfs_throttled_seconds_total|load_average_10s|system_seconds_total|user_seconds_total)' + # Drop less useful container / always zero filesystem metrics. + - sourceLabels: [__name__] + action: drop + regex: 'container_fs_(io_current|io_time_seconds_total|io_time_weighted_seconds_total|reads_merged_total|sector_reads_total|sector_writes_total|writes_merged_total)' + # Drop less useful / always zero container memory metrics. + - sourceLabels: [__name__] + action: drop + regex: 'container_memory_(mapped_file|swap)' + # Drop less useful container process metrics. + - sourceLabels: [__name__] + action: drop + regex: 'container_(file_descriptors|tasks_state|threads_max)' + # Drop container spec metrics that overlap with kube-state-metrics. + - sourceLabels: [__name__] + action: drop + regex: 'container_spec.*' + # Drop cgroup metrics with no pod. + - sourceLabels: [id, pod] + action: drop + regex: '.+;' + # - sourceLabels: [__name__, image] + # separator: ; + # regex: container_([a-z_]+); + # replacement: $1 + # action: drop + # - sourceLabels: [__name__] + # separator: ; + # regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) + # replacement: $1 + # action: drop + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + probesMetricRelabelings: [] + # - sourceLabels: [__name__, image] + # separator: ; + # regex: container_([a-z_]+); + # replacement: $1 + # action: drop + # - sourceLabels: [__name__] + # separator: ; + # regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) + # replacement: $1 + # action: drop + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + ## metrics_path is required to match upstream rules and charts + cAdvisorRelabelings: + - action: replace + sourceLabels: [__metrics_path__] + targetLabel: metrics_path + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + probesRelabelings: + - action: replace + sourceLabels: [__metrics_path__] + targetLabel: metrics_path + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + resourceRelabelings: + - action: replace + sourceLabels: [__metrics_path__] + targetLabel: metrics_path + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## 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: [] + # - sourceLabels: [__name__, image] + # separator: ; + # regex: container_([a-z_]+); + # replacement: $1 + # action: drop + # - sourceLabels: [__name__] + # separator: ; + # regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) + # replacement: $1 + # action: drop + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + ## metrics_path is required to match upstream rules and charts + relabelings: + - action: replace + sourceLabels: [__metrics_path__] + targetLabel: metrics_path + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping the kube controller manager +## +kubeControllerManager: + enabled: false + + ## If your kube controller manager is not deployed as a pod, specify IPs it can be found on + ## + endpoints: [] + # - 10.141.4.22 + # - 10.141.4.23 + # - 10.141.4.24 + + ## If using kubeControllerManager.endpoints only the port and targetPort are used + ## + service: + enabled: true + ## If null or unset, the value is determined dynamically based on target Kubernetes version due to change + ## of default port in Kubernetes 1.22. + ## + port: null + targetPort: null + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + # selector: + # component: kube-controller-manager + + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # component: kube-controller-manager + + ## Enable scraping kube-controller-manager over https. + ## Requires proper certs (not self-signed) and delegated authentication/authorization checks. + ## If null or unset, the value is determined dynamically based on target Kubernetes version. + ## + https: null + + # Skip TLS certificate validation when scraping + insecureSkipVerify: null + + # Name of the server to use when validating TLS certificate + serverName: null + + ## 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__] + + ## 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 + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping coreDns. Use either this or kubeDns +## +coreDns: + enabled: true + service: + enabled: true + port: 9153 + targetPort: 9153 + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + # selector: + # k8s-app: kube-dns + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # k8s-app: kube-dns + + ## 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__] + + ## 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 + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping kubeDns. Use either this or coreDns +## +kubeDns: + enabled: false + service: + dnsmasq: + port: 10054 + targetPort: 10054 + skydns: + port: 10055 + targetPort: 10055 + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + # selector: + # k8s-app: kube-dns + serviceMonitor: + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + jobLabel: jobLabel + selector: {} + # matchLabels: + # k8s-app: kube-dns + + ## 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__] + + ## 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 + + ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + dnsmasqMetricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + dnsmasqRelabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping etcd +## +kubeEtcd: + enabled: false + + ## If your etcd is not deployed as a pod, specify IPs it can be found on + ## + endpoints: [] + # - 10.141.4.22 + # - 10.141.4.23 + # - 10.141.4.24 + + ## Etcd service. If using kubeEtcd.endpoints only the port and targetPort are used + ## + service: + enabled: true + port: 2381 + targetPort: 2381 + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + # selector: + # component: etcd + + ## Configure secure access to the etcd cluster by loading a secret into prometheus and + ## specifying security configuration below. For example, with a secret named etcd-client-cert + ## + ## serviceMonitor: + ## scheme: https + ## insecureSkipVerify: false + ## serverName: localhost + ## caFile: /etc/prometheus/secrets/etcd-client-cert/etcd-ca + ## certFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client + ## keyFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client-key + ## + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + scheme: http + insecureSkipVerify: false + serverName: "" + caFile: "" + certFile: "" + keyFile: "" + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # component: etcd + + ## 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__] + + ## 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 + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping kube scheduler +## +kubeScheduler: + enabled: false + + ## If your kube scheduler is not deployed as a pod, specify IPs it can be found on + ## + endpoints: [] + # - 10.141.4.22 + # - 10.141.4.23 + # - 10.141.4.24 + + ## If using kubeScheduler.endpoints only the port and targetPort are used + ## + service: + enabled: true + ## If null or unset, the value is determined dynamically based on target Kubernetes version due to change + ## of default port in Kubernetes 1.23. + ## + port: null + targetPort: null + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + # selector: + # component: kube-scheduler + + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + ## Enable scraping kube-scheduler over https. + ## Requires proper certs (not self-signed) and delegated authentication/authorization checks. + ## If null or unset, the value is determined dynamically based on target Kubernetes version. + ## + https: null + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # component: kube-scheduler + + ## Skip TLS certificate validation when scraping + insecureSkipVerify: null + + ## Name of the server to use when validating TLS certificate + serverName: null + + ## 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__] + + ## 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 + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping kube proxy +## +kubeProxy: + enabled: false + + ## If your kube proxy is not deployed as a pod, specify IPs it can be found on + ## + endpoints: [] + # - 10.141.4.22 + # - 10.141.4.23 + # - 10.141.4.24 + + service: + enabled: true + port: 10249 + targetPort: 10249 + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + # selector: + # k8s-app: kube-proxy + + serviceMonitor: + enabled: true + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## port: Name of the port the metrics will be scraped from + ## + port: http-metrics + + jobLabel: jobLabel + selector: {} + # matchLabels: + # k8s-app: kube-proxy + + ## Enable scraping kube-proxy over https. + ## Requires proper certs (not self-signed) and delegated authentication/authorization checks + ## + https: false + + ## 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__] + + ## RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + ## + relabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## Additional labels + ## + additionalLabels: {} + # foo: bar + +## Component scraping kube state metrics +## +kubeStateMetrics: + enabled: true + +## Configuration for kube-state-metrics subchart +## +kube-state-metrics: + namespaceOverride: "" + rbac: + create: true + releaseLabel: true + prometheus: + monitor: + enabled: true + + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## Scrape Timeout. If not set, the Prometheus default scrape timeout is used. + ## + scrapeTimeout: "" + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + # Keep labels from scraped data, overriding server-side labels + ## + honorLabels: true + + ## 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__] + + ## 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 + + selfMonitor: + enabled: false + +## Deploy node exporter as a daemonset to all nodes +## +nodeExporter: + enabled: true + operatingSystems: + linux: + enabled: true + darwin: + enabled: true + + ## ForceDeployDashboard Create dashboard configmap even if nodeExporter deployment has been disabled + ## + forceDeployDashboards: false + +## Configuration for prometheus-node-exporter subchart +## +prometheus-node-exporter: + namespaceOverride: "" + podLabels: + ## Add the 'node-exporter' label to be used by serviceMonitor to match standard common usage in rules and grafana dashboards + ## + jobLabel: node-exporter + releaseLabel: true + extraArgs: + - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($|/) + - --collector.filesystem.fs-types-exclude=^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$ + service: + portName: http-metrics + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + prometheus: + monitor: + enabled: true + + jobLabel: jobLabel + + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## How long until a scrape request times out. If not set, the Prometheus default scape timeout is used. + ## + scrapeTimeout: "" + + ## proxyUrl: URL of a proxy that should be used for scraping. + ## + proxyUrl: "" + + ## 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: [] + # - sourceLabels: [__name__] + # separator: ; + # regex: ^node_mountstats_nfs_(event|operations|transport)_.+ + # replacement: $1 + # action: drop + + ## 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 + rbac: + ## If true, create PSPs for node-exporter + ## + pspEnabled: false + +## Manages Prometheus and Alertmanager components +## +prometheusOperator: + enabled: true + + ## Use '{{ template "kube-prometheus-stack.fullname" . }}-operator' by default + fullnameOverride: "" + + ## Number of old replicasets to retain ## + ## The default value is 10, 0 will garbage-collect old replicasets ## + revisionHistoryLimit: 10 + + ## Strategy of the deployment + ## + strategy: {} + + ## Prometheus-Operator v0.39.0 and later support TLS natively. + ## + tls: + enabled: true + # Value must match version names from https://golang.org/pkg/crypto/tls/#pkg-constants + tlsMinVersion: VersionTLS13 + # The default webhook port is 10250 in order to work out-of-the-box in GKE private clusters and avoid adding firewall rules. + internalPort: 10250 + + ## Admission webhook support for PrometheusRules resources added in Prometheus Operator 0.30 can be enabled to prevent incorrectly formatted + ## rules from making their way into prometheus and potentially preventing the container from starting + admissionWebhooks: + ## Valid values: Fail, Ignore, IgnoreOnInstallOnly + ## IgnoreOnInstallOnly - If Release.IsInstall returns "true", set "Ignore" otherwise "Fail" + failurePolicy: "" + ## The default timeoutSeconds is 10 and the maximum value is 30. + timeoutSeconds: 10 + enabled: true + ## A PEM encoded CA bundle which will be used to validate the webhook's server certificate. + ## If unspecified, system trust roots on the apiserver are used. + caBundle: "" + ## If enabled, generate a self-signed certificate, then patch the webhook configurations with the generated data. + ## On chart upgrades (or if the secret exists) the cert will not be re-generated. You can use this to provide your own + ## certs ahead of time if you wish. + ## + annotations: {} + # argocd.argoproj.io/hook: PreSync + # argocd.argoproj.io/hook-delete-policy: HookSucceeded + + namespaceSelector: {} + objectSelector: {} + + + deployment: + enabled: false + + ## Number of replicas + ## + replicas: 1 + + ## Strategy of the deployment + ## + strategy: {} + + # Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + podDisruptionBudget: {} + # maxUnavailable: 1 + # minAvailable: 1 + + ## Number of old replicasets to retain ## + ## The default value is 10, 0 will garbage-collect old replicasets ## + revisionHistoryLimit: 10 + + ## Prometheus-Operator v0.39.0 and later support TLS natively. + ## + tls: + enabled: true + # Value must match version names from https://golang.org/pkg/crypto/tls/#pkg-constants + tlsMinVersion: VersionTLS13 + # The default webhook port is 10250 in order to work out-of-the-box in GKE private clusters and avoid adding firewall rules. + internalPort: 10250 + + ## Service account for Prometheus Operator Webhook to use. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ## + serviceAccount: + automountServiceAccountToken: false + create: true + name: "" + + ## Configuration for Prometheus operator Webhook service + ## + service: + annotations: {} + labels: {} + clusterIP: "" + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + + ## Port to expose on each node + ## Only used if service.type is 'NodePort' + ## + nodePort: 31080 + + nodePortTls: 31443 + + ## Additional ports to open for Prometheus operator Webhook service + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services + ## + additionalPorts: [] + + ## Loadbalancer IP + ## Only use if service.type is "LoadBalancer" + ## + loadBalancerIP: "" + loadBalancerSourceRanges: [] + + ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + ## + externalTrafficPolicy: Cluster + + ## Service type + ## NodePort, ClusterIP, LoadBalancer + ## + type: ClusterIP + + ## List of IP addresses at which the Prometheus server service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + # ## Labels to add to the operator webhook deployment + # ## + labels: {} + + ## Annotations to add to the operator webhook deployment + ## + annotations: {} + + ## Labels to add to the operator webhook pod + ## + podLabels: {} + + ## Annotations to add to the operator webhook pod + ## + podAnnotations: {} + + ## Assign a PriorityClassName to pods if set + # priorityClassName: "" + + ## Define Log Format + # Use logfmt (default) or json logging + # logFormat: logfmt + + ## Decrease log verbosity to errors only + # logLevel: error + + ## Prometheus-operator webhook image + ## + image: + registry: quay.io + repository: rancher/mirrored-prometheus-operator-admission-webhook + # if not set appVersion field from Chart.yaml is used + tag: v0.75.1 + sha: "" + pullPolicy: IfNotPresent + + ## Define Log Format + # Use logfmt (default) or json logging + # logFormat: logfmt + + ## Decrease log verbosity to errors only + # logLevel: error + + + ## Liveness probe + ## + livenessProbe: + enabled: true + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + + ## Readiness probe + ## + readinessProbe: + enabled: true + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + + ## Resource limits & requests + ## + resources: {} + # limits: + # cpu: 200m + # memory: 200Mi + # requests: + # cpu: 100m + # memory: 100Mi + + # Required for use in managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico), + # because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working + ## + hostNetwork: false + + ## Define which Nodes the Pods are scheduled on. + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Tolerations for use with node taints + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal" + # value: "value" + # effect: "NoSchedule" + + ## Assign custom affinity rules to the prometheus operator + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + affinity: {} + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/e2e-az-name + # operator: In + # values: + # - e2e-az1 + # - e2e-az2 + dnsConfig: {} + # nameservers: + # - 1.2.3.4 + # searches: + # - ns1.svc.cluster-domain.example + # - my.dns.search.suffix + # options: + # - name: ndots + # value: "2" + # - name: edns0 + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault + + ## Container-specific security context configuration + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## + containerSecurityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + + ## If false then the user will opt out of automounting API credentials. + ## + automountServiceAccountToken: true + + patch: + enabled: true + image: + repository: rancher/mirrored-ingress-nginx-kube-webhook-certgen + tag: v1.4.3 + sha: "" + pullPolicy: IfNotPresent + resources: {} + ## Provide a priority class name to the webhook patching job + ## + priorityClassName: "" + ttlSecondsAfterFinished: 60 + annotations: {} + # argocd.argoproj.io/hook: PreSync + # argocd.argoproj.io/hook-delete-policy: HookSucceeded + podAnnotations: {} + nodeSelector: {} + affinity: {} + tolerations: [] + + ## SecurityContext holds pod-level security attributes and common container settings. + ## This defaults to non root user with uid 2000 and gid 2000. *v1.PodSecurityContext false + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## + securityContext: + runAsGroup: 2000 + runAsNonRoot: true + runAsUser: 2000 + seccompProfile: + type: RuntimeDefault + ## Service account for Prometheus Operator Webhook Job Patch to use. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ## + serviceAccount: + create: true + automountServiceAccountToken: true + + # Security context for create job container + createSecretJob: + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + + # Security context for patch job container + patchWebhookJob: + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + + # Use certmanager to generate webhook certs + certManager: + enabled: false + # self-signed root certificate + rootCert: + duration: "" # default to be 5y + admissionCert: + duration: "" # default to be 1y + # issuerRef: + # name: "issuer" + # kind: "ClusterIssuer" + + ## Namespaces to scope the interaction of the Prometheus Operator and the apiserver (allow list). + ## This is mutually exclusive with denyNamespaces. Setting this to an empty object will disable the configuration + ## + namespaces: {} + # releaseNamespace: true + # additional: + # - kube-system + + ## Namespaces not to scope the interaction of the Prometheus Operator (deny list). + ## + denyNamespaces: [] + + ## Filter namespaces to look for prometheus-operator custom resources + ## + alertmanagerInstanceNamespaces: [] + alertmanagerConfigNamespaces: [] + prometheusInstanceNamespaces: [] + thanosRulerInstanceNamespaces: [] + + ## The clusterDomain value will be added to the cluster.peer option of the alertmanager. + ## Without this specified option cluster.peer will have value alertmanager-monitoring-alertmanager-0.alertmanager-operated:9094 (default value) + ## With this specified option cluster.peer will have value alertmanager-monitoring-alertmanager-0.alertmanager-operated.namespace.svc.cluster-domain:9094 + ## + # clusterDomain: "cluster.local" + + networkPolicy: + ## Enable creation of NetworkPolicy resources. + ## + enabled: false + + ## Flavor of the network policy to use. + # Can be: + # * kubernetes for networking.k8s.io/v1/NetworkPolicy + # * cilium for cilium.io/v2/CiliumNetworkPolicy + flavor: kubernetes + + # cilium: + # egress: + + ## match labels used in selector + # matchLabels: {} + + ## Service account for Prometheus Operator to use. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ## + serviceAccount: + create: true + name: "" + automountServiceAccountToken: true + + ## Configuration for Prometheus operator service + ## + service: + annotations: {} + labels: {} + clusterIP: "" + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + + ## Port to expose on each node + ## Only used if service.type is 'NodePort' + ## + nodePort: 30080 + + nodePortTls: 30443 + + ## Additional ports to open for Prometheus operator service + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services + ## + additionalPorts: [] + + ## Loadbalancer IP + ## Only use if service.type is "LoadBalancer" + ## + loadBalancerIP: "" + loadBalancerSourceRanges: [] + + ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + ## + externalTrafficPolicy: Cluster + + ## Service type + ## NodePort, ClusterIP, LoadBalancer + ## + type: ClusterIP + + ## List of IP addresses at which the Prometheus server service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + # ## Labels to add to the operator deployment + # ## + labels: {} + + ## Annotations to add to the operator deployment + ## + annotations: {} + + ## Labels to add to the operator pod + ## + podLabels: {} + + ## Annotations to add to the operator pod + ## + podAnnotations: {} + + ## Assign a PriorityClassName to pods if set + # priorityClassName: "" + + ## Define Log Format + # Use logfmt (default) or json logging + # logFormat: logfmt + + ## Decrease log verbosity to errors only + # logLevel: error + + kubeletService: + ## If true, the operator will create and maintain a service for scraping kubelets + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/helm/prometheus-operator/README.md + ## + enabled: true + namespace: kube-system + selector: "" + ## Use '{{ template "kube-prometheus-stack.fullname" . }}-kubelet' by default + name: "" + + ## Create a servicemonitor for the operator + ## + serviceMonitor: + ## If true, create a serviceMonitor for prometheus operator + ## + selfMonitor: true + + ## Labels for ServiceMonitor + additionalLabels: {} + + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## Scrape timeout. If not set, the Prometheus default scrape timeout is used. + scrapeTimeout: "" + + ## Metric relabel configs to apply to samples before ingestion. + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + # relabel configs to apply to samples before ingestion. + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Resource limits & requests + ## + resources: {} + # limits: + # cpu: 200m + # memory: 200Mi + # requests: + # cpu: 100m + # memory: 100Mi + + ## Operator Environment + ## env: + ## VARIABLE: value + env: + GOGC: "30" + + # Required for use in managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico), + # because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working + ## + hostNetwork: false + + ## Define which Nodes the Pods are scheduled on. + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Tolerations for use with node taints + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal" + # value: "value" + # effect: "NoSchedule" + + ## Assign custom affinity rules to the prometheus operator + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + affinity: {} + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/e2e-az-name + # operator: In + # values: + # - e2e-az1 + # - e2e-az2 + dnsConfig: {} + # nameservers: + # - 1.2.3.4 + # searches: + # - ns1.svc.cluster-domain.example + # - my.dns.search.suffix + # options: + # - name: ndots + # value: "2" + # - name: edns0 + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault + + ## Container-specific security context configuration + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## + containerSecurityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + + # Enable vertical pod autoscaler support for prometheus-operator + verticalPodAutoscaler: + enabled: false + + # Recommender 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: + # - name: custom-recommender-performance + + # List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory + controlledResources: [] + # Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits. + # controlledValues: RequestsAndLimits + + # Define the max allowed resources for the pod + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # Define the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + + 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 + + ## Prometheus-operator image + ## + image: + repository: rancher/mirrored-prometheus-operator-prometheus-operator + tag: v0.75.1 + sha: "" + pullPolicy: IfNotPresent + + ## Prometheus image to use for prometheuses managed by the operator + ## + # prometheusDefaultBaseImage: prometheus/prometheus + + ## Prometheus image registry to use for prometheuses managed by the operator + ## + # prometheusDefaultBaseImageRegistry: quay.io + + ## Alertmanager image to use for alertmanagers managed by the operator + ## + # alertmanagerDefaultBaseImage: prometheus/alertmanager + + ## Alertmanager image registry to use for alertmanagers managed by the operator + ## + # alertmanagerDefaultBaseImageRegistry: quay.io + + ## Prometheus-config-reloader + ## + prometheusConfigReloader: + image: + repository: rancher/mirrored-prometheus-operator-prometheus-config-reloader + tag: v0.75.1 + sha: "" + + # add prometheus config reloader liveness and readiness probe. Default: false + enableProbe: false + + # resource config for prometheusConfigReloader + resources: {} + # requests: + # cpu: 200m + # memory: 50Mi + # limits: + # cpu: 200m + # memory: 50Mi + + ## Thanos side-car image when configured + ## + thanosImage: + repository: rancher/mirrored-thanos-thanos + tag: v0.35.1 + sha: "" + + ## Set a Label Selector to filter watched prometheus and prometheusAgent + ## + prometheusInstanceSelector: "" + + ## Set a Label Selector to filter watched alertmanager + ## + alertmanagerInstanceSelector: "" + + ## Set a Label Selector to filter watched thanosRuler + thanosRulerInstanceSelector: "" + + ## Set a Field Selector to filter watched secrets + ## + secretFieldSelector: "type!=kubernetes.io/dockercfg,type!=kubernetes.io/service-account-token,type!=helm.sh/release.v1" + + ## If false then the user will opt out of automounting API credentials. + ## + automountServiceAccountToken: true + + ## Additional volumes + ## + extraVolumes: [] + + ## Additional volume mounts + ## + extraVolumeMounts: [] + +## Deploy a Prometheus instance +## +prometheus: + enabled: true + + ## Toggle prometheus into agent mode + ## Note many of features described below (e.g. rules, query, alerting, remote read, thanos) will not work in agent mode. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/designs/prometheus-agent.md + ## + agentMode: false + + ## Annotations for Prometheus + ## + annotations: {} + + ## Configure network policy for the prometheus + networkPolicy: + enabled: false + + ## Flavor of the network policy to use. + # Can be: + # * kubernetes for networking.k8s.io/v1/NetworkPolicy + # * cilium for cilium.io/v2/CiliumNetworkPolicy + flavor: kubernetes + + # cilium: + # endpointSelector: + # egress: + # ingress: + + # egress: + # - {} + # ingress: + # - {} + # podSelector: + # matchLabels: + # app: prometheus + + ## Service account for Prometheuses to use. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ## + serviceAccount: + create: true + name: "" + annotations: {} + automountServiceAccountToken: true + + # Service for thanos service discovery on sidecar + # Enable this can make Thanos Query can use + # `--store=dnssrv+_grpc._tcp.${kube-prometheus-stack.fullname}-thanos-discovery.${namespace}.svc.cluster.local` to discovery + # Thanos sidecar on prometheus nodes + # (Please remember to change ${kube-prometheus-stack.fullname} and ${namespace}. Not just copy and paste!) + thanosService: + enabled: false + annotations: {} + labels: {} + + ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + ## + externalTrafficPolicy: Cluster + + ## Service type + ## + type: ClusterIP + + ## Service dual stack + ## + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + + ## gRPC port config + portName: grpc + port: 10901 + targetPort: "grpc" + + ## HTTP port config (for metrics) + httpPortName: http + httpPort: 10902 + targetHttpPort: "http" + + ## ClusterIP to assign + # Default is to make this a headless service ("None") + clusterIP: "None" + + ## Port to expose on each node, if service type is NodePort + ## + nodePort: 30901 + httpNodePort: 30902 + + # ServiceMonitor to scrape Sidecar metrics + # Needs thanosService to be enabled as well + thanosServiceMonitor: + enabled: false + interval: "" + + ## Additional labels + ## + additionalLabels: {} + + ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS. + scheme: "" + + ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS. + ## Of type: https://github.com/coreos/prometheus-operator/blob/main/Documentation/api.md#tlsconfig + tlsConfig: {} + + bearerTokenFile: + + ## Metric relabel configs to apply to samples before ingestion. + metricRelabelings: [] + + ## relabel configs to apply to samples before ingestion. + relabelings: [] + + # Service for external access to sidecar + # Enabling this creates a service to expose thanos-sidecar outside the cluster. + thanosServiceExternal: + enabled: false + annotations: {} + labels: {} + loadBalancerIP: "" + loadBalancerSourceRanges: [] + + ## gRPC port config + portName: grpc + port: 10901 + targetPort: "grpc" + + ## HTTP port config (for metrics) + httpPortName: http + httpPort: 10902 + targetHttpPort: "http" + + ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + ## + externalTrafficPolicy: Cluster + + ## Service type + ## + type: LoadBalancer + + ## Port to expose on each node + ## + nodePort: 30901 + httpNodePort: 30902 + + ## Configuration for Prometheus service + ## + service: + annotations: {} + labels: {} + clusterIP: "" + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + + ## Port for Prometheus Service to listen on + ## + port: 9090 + + ## To be used with a proxy extraContainer port + targetPort: 8081 + + ## Port for Prometheus Reloader to listen on + ## + reloaderWebPort: 8080 + + ## List of IP addresses at which the Prometheus server service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + ## Port to expose on each node + ## Only used if service.type is 'NodePort' + ## + nodePort: 30090 + + ## Loadbalancer IP + ## Only use if service.type is "LoadBalancer" + loadBalancerIP: "" + loadBalancerSourceRanges: [] + + ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + ## + externalTrafficPolicy: Cluster + + ## Service type + ## + type: ClusterIP + + ## Additional ports to open for Prometheus service + ## + additionalPorts: [] + # additionalPorts: + # - name: oauth-proxy + # port: 8081 + # targetPort: 8081 + # - name: oauth-metrics + # port: 8082 + # targetPort: 8082 + + ## Consider that all endpoints are considered "ready" even if the Pods themselves are not + ## Ref: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec + publishNotReadyAddresses: false + + ## If you want to make sure that connections from a particular client are passed to the same Pod each time + ## Accepts 'ClientIP' or 'None' + ## + sessionAffinity: None + + ## If you want to modify the ClientIP sessionAffinity timeout + ## The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP" + ## + sessionAffinityConfig: + clientIP: + timeoutSeconds: 10800 + + ## Configuration for creating a separate Service for each statefulset Prometheus replica + ## + servicePerReplica: + enabled: false + annotations: {} + + ## Port for Prometheus Service per replica to listen on + ## + port: 9090 + + ## To be used with a proxy extraContainer port + targetPort: 9090 + + ## Port to expose on each node + ## Only used if servicePerReplica.type is 'NodePort' + ## + nodePort: 30091 + + ## Loadbalancer source IP ranges + ## Only used if servicePerReplica.type is "LoadBalancer" + loadBalancerSourceRanges: [] + + ## Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + ## + externalTrafficPolicy: Cluster + + ## Service type + ## + type: ClusterIP + + ## Service dual stack + ## + ipDualStack: + enabled: false + ipFamilies: ["IPv6", "IPv4"] + ipFamilyPolicy: "PreferDualStack" + + ## Configure pod disruption budgets for Prometheus + ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget + ## + podDisruptionBudget: + enabled: false + minAvailable: 1 + maxUnavailable: "" + + # Ingress exposes thanos sidecar outside the cluster + thanosIngress: + 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 + + annotations: {} + labels: {} + servicePort: 10901 + + ## Port to expose on each node + ## Only used if service.type is 'NodePort' + ## + nodePort: 30901 + + ## Hosts must be provided if Ingress is enabled. + ## + hosts: [] + # - thanos-gateway.domain.com + + ## Paths to use for ingress rules + ## + paths: [] + # - / + + ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) + ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types + # pathType: ImplementationSpecific + + ## TLS configuration for Thanos Ingress + ## Secret must be manually created in the namespace + ## + tls: [] + # - secretName: thanos-gateway-tls + # hosts: + # - thanos-gateway.domain.com + # + + ## ExtraSecret can be used to store various data in an extra secret + ## (use it for example to store hashed basic auth credentials) + extraSecret: + ## if not set, name will be auto generated + # name: "" + annotations: {} + data: {} + # auth: | + # foo:$apr1$OFG3Xybp$ckL0FHDAkoXYIlH9.cysT0 + # someoneelse:$apr1$DMZX2Z4q$6SbQIfyuLQd.xmo/P0m2c. + + ingress: + 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 + + annotations: {} + labels: {} + + ## Redirect ingress to an additional defined port on the service + # servicePort: 8081 + + ## Hostnames. + ## Must be provided if Ingress is enabled. + ## + # hosts: + # - prometheus.domain.com + hosts: [] + + ## Paths to use for ingress rules - one path should match the prometheusSpec.routePrefix + ## + paths: [] + # - / + + ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) + ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types + # pathType: ImplementationSpecific + + ## TLS configuration for Prometheus Ingress + ## Secret must be manually created in the namespace + ## + tls: [] + # - secretName: prometheus-general-tls + # hosts: + # - prometheus.example.com + + ## Configuration for creating an Ingress that will map to each Prometheus replica service + ## prometheus.servicePerReplica must be enabled + ## + ingressPerReplica: + 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 + + annotations: {} + labels: {} + + ## Final form of the hostname for each per replica ingress is + ## {{ ingressPerReplica.hostPrefix }}-{{ $replicaNumber }}.{{ ingressPerReplica.hostDomain }} + ## + ## Prefix for the per replica ingress that will have `-$replicaNumber` + ## appended to the end + hostPrefix: "" + ## Domain that will be used for the per replica ingress + hostDomain: "" + + ## Paths to use for ingress rules + ## + paths: [] + # - / + + ## For Kubernetes >= 1.18 you should specify the pathType (determines how Ingress paths should be matched) + ## See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#better-path-matching-with-path-types + # pathType: ImplementationSpecific + + ## Secret name containing the TLS certificate for Prometheus per replica ingress + ## Secret must be manually created in the namespace + tlsSecretName: "" + + ## Separated secret for each per replica Ingress. Can be used together with cert-manager + ## + tlsSecretPerReplica: + enabled: false + ## Final form of the secret for each per replica ingress is + ## {{ tlsSecretPerReplica.prefix }}-{{ $replicaNumber }} + ## + prefix: "prometheus" + + ## Configure additional options for default pod security policy for Prometheus + ## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + podSecurityPolicy: + allowedCapabilities: [] + allowedHostPaths: [] + volumes: [] + + serviceMonitor: + ## If true, create a serviceMonitor for prometheus + ## + selfMonitor: true + + ## Scrape interval. If not set, the Prometheus default scrape interval is used. + ## + interval: "" + + ## Additional labels + ## + additionalLabels: {} + + ## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + ## + sampleLimit: 0 + + ## TargetLimit defines a limit on the number of scraped targets that will be accepted. + ## + targetLimit: 0 + + ## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelLimit: 0 + + ## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelNameLengthLimit: 0 + + ## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. + ## + labelValueLengthLimit: 0 + + ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS. + scheme: "" + + ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS. + ## Of type: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#tlsconfig + tlsConfig: {} + + bearerTokenFile: + + ## Metric relabel configs to apply to samples before ingestion. + ## + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + # relabel configs to apply to samples before ingestion. + ## + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + + ## Additional Endpoints + ## + additionalEndpoints: [] + # - port: oauth-metrics + # path: /metrics + + ## Settings affecting prometheusSpec + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#prometheusspec + ## + prometheusSpec: + ## Statefulset's persistent volume claim retention policy + ## pvcDeleteOnStsDelete and pvcDeleteOnStsScale determine whether + ## statefulset's PVCs are deleted (true) or retained (false) on scaling down + ## and deleting statefulset, respectively. Requires 1.27.0+. + ## Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#persistentvolumeclaim-retention + persistentVolumeClaimRetentionPolicy: {} + # whenDeleted: Retain + # whenScaled: Retain + + ## If true, pass --storage.tsdb.max-block-duration=2h to prometheus. This is already done if using Thanos + ## + ## AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in the pod, + ## If the field isn’t set, the operator mounts the service account token by default. + ## Warning: be aware that by default, Prometheus requires the service account token for Kubernetes service discovery, + ## It is possible to use strategic merge patch to project the service account token into the ‘prometheus’ container. + automountServiceAccountToken: true + + disableCompaction: false + ## APIServerConfig + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#apiserverconfig + ## + apiserverConfig: {} + + ## Allows setting additional arguments for the Prometheus container + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.Prometheus + additionalArgs: [] + + ## Interval between consecutive scrapes. + ## Defaults to 30s. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/release-0.44/pkg/prometheus/promcfg.go#L180-L183 + ## + scrapeInterval: "30s" + + ## Number of seconds to wait for target to respond before erroring + ## + # scrapeTimeout: "" + + ## List of scrape classes to expose to scraping objects such as + ## PodMonitors, ServiceMonitors, Probes and ScrapeConfigs. + ## + scrapeClasses: [] + # - name: istio-mtls + # default: false + # tlsConfig: + # caFile: /etc/prometheus/secrets/istio.default/root-cert.pem + # certFile: /etc/prometheus/secrets/istio.default/cert-chain.pem + + ## Interval between consecutive evaluations. + ## + evaluationInterval: "30s" + + ## ListenLocal makes the Prometheus server listen on loopback, so that it does not bind against the Pod IP. + ## + listenLocal: false + + ## EnableAdminAPI enables Prometheus the administrative HTTP API which includes functionality such as deleting time series. + ## This is disabled by default. + ## ref: https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-admin-apis + ## + enableAdminAPI: false + + ## Sets version of Prometheus overriding the Prometheus version as derived + ## from the image tag. Useful in cases where the tag does not follow semver v2. + version: "" + + ## WebTLSConfig defines the TLS parameters for HTTPS + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#webtlsconfig + web: {} + + ## Exemplars related settings that are runtime reloadable. + ## It requires to enable the exemplar storage feature to be effective. + exemplars: "" + ## Maximum number of exemplars stored in memory for all series. + ## If not set, Prometheus uses its default value. + ## A value of zero or less than zero disables the storage. + # maxSize: 100000 + + # EnableFeatures API enables access to Prometheus disabled features. + # ref: https://prometheus.io/docs/prometheus/latest/disabled_features/ + enableFeatures: [] + # - exemplar-storage + + ## Image of Prometheus. + ## + image: + repository: rancher/mirrored-prometheus-prometheus + tag: v2.53.1 + sha: "" + + ## Tolerations for use with node taints + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal" + # value: "value" + # effect: "NoSchedule" + + ## If specified, the pod's topology spread constraints. + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app: prometheus + + ## Alertmanagers to which alerts will be sent + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#alertmanagerendpoints + ## + ## Default configuration will connect to the alertmanager deployed as part of this release + ## + alertingEndpoints: [] + # - name: "" + # namespace: "" + # port: http + # scheme: http + # pathPrefix: "" + # tlsConfig: {} + # bearerTokenFile: "" + # apiVersion: v2 + + ## External labels to add to any time series or alerts when communicating with external systems + ## + externalLabels: {} + + ## enable --web.enable-remote-write-receiver flag on prometheus-server + ## + enableRemoteWriteReceiver: false + + ## Name of the external label used to denote replica name + ## + replicaExternalLabelName: "" + + ## If true, the Operator won't add the external label used to denote replica name + ## + replicaExternalLabelNameClear: false + + ## Name of the external label used to denote Prometheus instance name + ## + prometheusExternalLabelName: "" + + ## If true, the Operator won't add the external label used to denote Prometheus instance name + ## + prometheusExternalLabelNameClear: false + + ## External URL at which Prometheus will be reachable. + ## + externalUrl: "" + + ## Define which Nodes the Pods are scheduled on. + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Secrets is a list of Secrets in the same namespace as the Prometheus object, which shall be mounted into the Prometheus Pods. + ## The Secrets are mounted into /etc/prometheus/secrets/. Secrets changes after initial creation of a Prometheus object are not + ## reflected in the running Pods. To change the secrets mounted into the Prometheus Pods, the object must be deleted and recreated + ## with the new list of secrets. + ## + secrets: [] + + ## ConfigMaps is a list of ConfigMaps in the same namespace as the Prometheus object, which shall be mounted into the Prometheus Pods. + ## The ConfigMaps are mounted into /etc/prometheus/configmaps/. + ## + configMaps: [] + + ## QuerySpec defines the query command line flags when starting Prometheus. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#queryspec + ## + query: {} + + ## If nil, select own namespace. Namespaces to be selected for PrometheusRules discovery. + ruleNamespaceSelector: {} + ## Example which selects PrometheusRules in namespaces with label "prometheus" set to "somelabel" + # ruleNamespaceSelector: + # matchLabels: + # prometheus: somelabel + + ## If true, a nil or {} value for prometheus.prometheusSpec.ruleSelector will cause the + ## prometheus resource to be created with selectors based on values in the helm deployment, + ## which will also match the PrometheusRule resources created + ## + ruleSelectorNilUsesHelmValues: false + + ## PrometheusRules to be selected for target discovery. + ## If {}, select all PrometheusRules + ## + ruleSelector: {} + ## Example which select all PrometheusRules resources + ## with label "prometheus" with values any of "example-rules" or "example-rules-2" + # ruleSelector: + # matchExpressions: + # - key: prometheus + # operator: In + # values: + # - example-rules + # - example-rules-2 + # + ## Example which select all PrometheusRules resources with label "role" set to "example-rules" + # ruleSelector: + # matchLabels: + # role: example-rules + + ## If true, a nil or {} value for prometheus.prometheusSpec.serviceMonitorSelector will cause the + ## prometheus resource to be created with selectors based on values in the helm deployment, + ## which will also match the servicemonitors created + ## + serviceMonitorSelectorNilUsesHelmValues: false + + ## ServiceMonitors to be selected for target discovery. + ## If {}, select all ServiceMonitors + ## + serviceMonitorSelector: {} + ## Example which selects ServiceMonitors with label "prometheus" set to "somelabel" + # serviceMonitorSelector: + # matchLabels: + # prometheus: somelabel + + ## Namespaces to be selected for ServiceMonitor discovery. + ## + serviceMonitorNamespaceSelector: {} + ## Example which selects ServiceMonitors in namespaces with label "prometheus" set to "somelabel" + # serviceMonitorNamespaceSelector: + # matchLabels: + # prometheus: somelabel + + ## If true, a nil or {} value for prometheus.prometheusSpec.podMonitorSelector will cause the + ## prometheus resource to be created with selectors based on values in the helm deployment, + ## which will also match the podmonitors created + ## + podMonitorSelectorNilUsesHelmValues: false + + ## PodMonitors to be selected for target discovery. + ## If {}, select all PodMonitors + ## + podMonitorSelector: {} + ## Example which selects PodMonitors with label "prometheus" set to "somelabel" + # podMonitorSelector: + # matchLabels: + # prometheus: somelabel + + ## If nil, select own namespace. Namespaces to be selected for PodMonitor discovery. + podMonitorNamespaceSelector: {} + ## Example which selects PodMonitor in namespaces with label "prometheus" set to "somelabel" + # podMonitorNamespaceSelector: + # matchLabels: + # prometheus: somelabel + + ## If true, a nil or {} value for prometheus.prometheusSpec.probeSelector will cause the + ## prometheus resource to be created with selectors based on values in the helm deployment, + ## which will also match the probes created + ## + probeSelectorNilUsesHelmValues: true + + ## Probes to be selected for target discovery. + ## If {}, select all Probes + ## + probeSelector: {} + ## Example which selects Probes with label "prometheus" set to "somelabel" + # probeSelector: + # matchLabels: + # prometheus: somelabel + + ## If nil, select own namespace. Namespaces to be selected for Probe discovery. + probeNamespaceSelector: {} + ## Example which selects Probe in namespaces with label "prometheus" set to "somelabel" + # probeNamespaceSelector: + # matchLabels: + # prometheus: somelabel + + ## If true, a nil or {} value for prometheus.prometheusSpec.scrapeConfigSelector will cause the + ## prometheus resource to be created with selectors based on values in the helm deployment, + ## which will also match the scrapeConfigs created + ## + scrapeConfigSelectorNilUsesHelmValues: true + + ## scrapeConfigs to be selected for target discovery. + ## If {}, select all scrapeConfigs + ## + scrapeConfigSelector: {} + ## Example which selects scrapeConfigs with label "prometheus" set to "somelabel" + # scrapeConfigSelector: + # matchLabels: + # prometheus: somelabel + + ## If nil, select own namespace. Namespaces to be selected for scrapeConfig discovery. + scrapeConfigNamespaceSelector: {} + ## Example which selects scrapeConfig in namespaces with label "prometheus" set to "somelabel" + # scrapeConfigNamespaceSelector: + # matchLabels: + # prometheus: somelabel + + ## How long to retain metrics + ## + retention: 10d + + ## Maximum size of metrics + ## + retentionSize: "" + + ## Allow out-of-order/out-of-bounds samples ingested into Prometheus for a specified duration + ## See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#tsdb + tsdb: + outOfOrderTimeWindow: 0s + + ## Enable compression of the write-ahead log using Snappy. + ## + walCompression: true + + ## If true, the Operator won't process any Prometheus configuration changes + ## + paused: false + + ## Number of replicas of each shard to deploy for a Prometheus deployment. + ## Number of replicas multiplied by shards is the total number of Pods created. + ## + replicas: 1 + + ## EXPERIMENTAL: Number of shards to distribute targets onto. + ## Number of replicas multiplied by shards is the total number of Pods created. + ## Note that scaling down shards will not reshard data onto remaining instances, it must be manually moved. + ## Increasing shards will not reshard data either but it will continue to be available from the same instances. + ## To query globally use Thanos sidecar and Thanos querier or remote write data to a central location. + ## Sharding is done on the content of the `__address__` target meta-label. + ## + shards: 1 + + ## Log level for Prometheus be configured in + ## + logLevel: info + + ## Log format for Prometheus be configured in + ## + logFormat: logfmt + + ## Prefix used to register routes, overriding externalUrl route. + ## Useful for proxies that rewrite URLs. + ## + routePrefix: / + + ## Standard object's metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata + ## Metadata Labels and Annotations gets propagated to the prometheus pods. + ## + podMetadata: {} + # labels: + # app: prometheus + # k8s-app: prometheus + + ## Pod anti-affinity can prevent the scheduler from placing Prometheus replicas on the same node. + ## The default value "soft" means that the scheduler should *prefer* to not schedule two replica pods onto the same node but no guarantee is provided. + ## The value "hard" means that the scheduler is *required* to not schedule two replica pods onto the same node. + ## The value "" will disable pod anti-affinity so that no anti-affinity rules will be configured. + podAntiAffinity: "" + + ## If anti-affinity is enabled sets the topologyKey to use for anti-affinity. + ## This can be changed to, for example, failure-domain.beta.kubernetes.io/zone + ## + podAntiAffinityTopologyKey: kubernetes.io/hostname + + ## Assign custom affinity rules to the prometheus instance + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + affinity: {} + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/e2e-az-name + # operator: In + # values: + # - e2e-az1 + # - e2e-az2 + + ## The remote_read spec configuration for Prometheus. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#remotereadspec + remoteRead: [] + # - url: http://remote1/read + ## additionalRemoteRead is appended to remoteRead + additionalRemoteRead: [] + + ## The remote_write spec configuration for Prometheus. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#remotewritespec + remoteWrite: [] + # - url: http://remote1/push + ## additionalRemoteWrite is appended to remoteWrite + additionalRemoteWrite: [] + + ## Enable/Disable Grafana dashboards provisioning for prometheus remote write feature + remoteWriteDashboards: false + + ## Resource limits & requests + ## + resources: + limits: + memory: 3000Mi + cpu: 1000m + requests: + memory: 750Mi + cpu: 750m + + ## Prometheus StorageSpec for persistent data + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/storage.md + ## + storageSpec: {} + ## Using PersistentVolumeClaim + ## + # volumeClaimTemplate: + # spec: + # storageClassName: gluster + # accessModes: ["ReadWriteOnce"] + # resources: + # requests: + # storage: 50Gi + # selector: {} + + ## Using tmpfs volume + ## + # emptyDir: + # medium: Memory + + # Additional volumes on the output StatefulSet definition. + volumes: + - name: nginx-home + emptyDir: {} + - name: prometheus-nginx + configMap: + name: prometheus-nginx-proxy-config + defaultMode: 438 + + # Additional VolumeMounts on the output StatefulSet definition. + volumeMounts: [] + + ## AdditionalScrapeConfigs allows specifying additional Prometheus scrape configurations. Scrape configurations + ## are appended to the configurations generated by the Prometheus Operator. Job configurations must have the form + ## as specified in the official Prometheus documentation: + ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config. As scrape configs are + ## appended, the user is responsible to make sure it is valid. Note that using this feature may expose the possibility + ## to break upgrades of Prometheus. It is advised to review Prometheus release notes to ensure that no incompatible + ## scrape configs are going to break Prometheus after the upgrade. + ## AdditionalScrapeConfigs can be defined as a list or as a templated string. + ## + ## The scrape configuration example below will find master nodes, provided they have the name .*mst.*, relabel the + ## port to 2379 and allow etcd scraping provided it is running on all Kubernetes master nodes + ## + additionalScrapeConfigs: [] + # - job_name: kube-etcd + # kubernetes_sd_configs: + # - role: node + # scheme: https + # tls_config: + # ca_file: /etc/prometheus/secrets/etcd-client-cert/etcd-ca + # cert_file: /etc/prometheus/secrets/etcd-client-cert/etcd-client + # key_file: /etc/prometheus/secrets/etcd-client-cert/etcd-client-key + # relabel_configs: + # - action: labelmap + # regex: __meta_kubernetes_node_label_(.+) + # - source_labels: [__address__] + # action: replace + # targetLabel: __address__ + # regex: ([^:;]+):(\d+) + # replacement: ${1}:2379 + # - source_labels: [__meta_kubernetes_node_name] + # action: keep + # regex: .*mst.* + # - source_labels: [__meta_kubernetes_node_name] + # action: replace + # targetLabel: node + # regex: (.*) + # replacement: ${1} + # metric_relabel_configs: + # - regex: (kubernetes_io_hostname|failure_domain_beta_kubernetes_io_region|beta_kubernetes_io_os|beta_kubernetes_io_arch|beta_kubernetes_io_instance_type|failure_domain_beta_kubernetes_io_zone) + # action: labeldrop + # + ## If scrape config contains a repetitive section, you may want to use a template. + ## In the following example, you can see how to define `gce_sd_configs` for multiple zones + # additionalScrapeConfigs: | + # - job_name: "node-exporter" + # gce_sd_configs: + # {{range $zone := .Values.gcp_zones}} + # - project: "project1" + # zone: "{{$zone}}" + # port: 9100 + # {{end}} + # relabel_configs: + # ... + + + ## If additional scrape configurations are already deployed in a single secret file you can use this section. + ## Expected values are the secret name and key + ## Cannot be used with additionalScrapeConfigs + additionalScrapeConfigsSecret: {} + # enabled: false + # name: + # key: + + ## additionalPrometheusSecretsAnnotations allows to add annotations to the kubernetes secret. This can be useful + ## when deploying via spinnaker to disable versioning on the secret, strategy.spinnaker.io/versioned: 'false' + additionalPrometheusSecretsAnnotations: {} + + ## AdditionalAlertManagerConfigs allows for manual configuration of alertmanager jobs in the form as specified + ## in the official Prometheus documentation https://prometheus.io/docs/prometheus/latest/configuration/configuration/#. + ## AlertManager configurations specified are appended to the configurations generated by the Prometheus Operator. + ## As AlertManager configs are appended, the user is responsible to make sure it is valid. Note that using this + ## feature may expose the possibility to break upgrades of Prometheus. It is advised to review Prometheus release + ## notes to ensure that no incompatible AlertManager configs are going to break Prometheus after the upgrade. + ## + additionalAlertManagerConfigs: [] + # - consul_sd_configs: + # - server: consul.dev.test:8500 + # scheme: http + # datacenter: dev + # tag_separator: ',' + # services: + # - metrics-prometheus-alertmanager + + ## If additional alertmanager configurations are already deployed in a single secret, or you want to manage + ## them separately from the helm deployment, you can use this section. + ## Expected values are the secret name and key + ## Cannot be used with additionalAlertManagerConfigs + additionalAlertManagerConfigsSecret: {} + # name: + # key: + # optional: false + + ## AdditionalAlertRelabelConfigs allows specifying Prometheus alert relabel configurations. Alert relabel configurations specified are appended + ## to the configurations generated by the Prometheus Operator. Alert relabel configurations specified must have the form as specified in the + ## official Prometheus documentation: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs. + ## As alert relabel configs are appended, the user is responsible to make sure it is valid. Note that using this feature may expose the + ## possibility to break upgrades of Prometheus. It is advised to review Prometheus release notes to ensure that no incompatible alert relabel + ## configs are going to break Prometheus after the upgrade. + ## + additionalAlertRelabelConfigs: [] + # - separator: ; + # regex: prometheus_replica + # replacement: $1 + # action: labeldrop + + ## If additional alert relabel configurations are already deployed in a single secret, or you want to manage + ## them separately from the helm deployment, you can use this section. + ## Expected values are the secret name and key + ## Cannot be used with additionalAlertRelabelConfigs + additionalAlertRelabelConfigsSecret: {} + # name: + # key: + + ## SecurityContext holds pod-level security attributes and common container settings. + ## This defaults to non root user with uid 1000 and gid 2000. + ## https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md + ## + securityContext: + runAsGroup: 2000 + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 2000 + seccompProfile: + type: RuntimeDefault + + ## Priority class assigned to the Pods + ## + priorityClassName: "" + + ## Thanos configuration allows configuring various aspects of a Prometheus server in a Thanos environment. + ## This section is experimental, it may change significantly without deprecation notice in any release. + ## This is experimental and may change significantly without backward compatibility in any release. + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#thanosspec + ## + thanos: {} + # secretProviderClass: + # provider: gcp + # parameters: + # secrets: | + # - resourceName: "projects/$PROJECT_ID/secrets/testsecret/versions/latest" + # fileName: "objstore.yaml" + ## ObjectStorageConfig configures object storage in Thanos. + # objectStorageConfig: + # # use existing secret, if configured, objectStorageConfig.secret will not be used + # existingSecret: {} + # # name: "" + # # key: "" + # # will render objectStorageConfig secret data and configure it to be used by Thanos custom resource, + # # ignored when prometheusspec.thanos.objectStorageConfig.existingSecret is set + # # https://thanos.io/tip/thanos/storage.md/#s3 + # secret: {} + # # type: S3 + # # config: + # # bucket: "" + # # endpoint: "" + # # region: "" + # # access_key: "" + # # secret_key: "" + + proxy: + image: + repository: rancher/mirrored-library-nginx + tag: 1.24.0-alpine + + ## Containers allows injecting additional containers. This is meant to allow adding an authentication proxy to a Prometheus pod. + ## if using proxy extraContainer update targetPort with proxy container port + containers: | + - name: prometheus-proxy + args: + - nginx + - -g + - daemon off; + - -c + - /nginx/nginx.conf + image: "{{ template "system_default_registry" . }}{{ .Values.prometheus.prometheusSpec.proxy.image.repository }}:{{ .Values.prometheus.prometheusSpec.proxy.image.tag }}" + ports: + - containerPort: 8081 + name: nginx-http + protocol: TCP + volumeMounts: + - mountPath: /nginx + name: prometheus-nginx + - mountPath: /var/cache/nginx + name: nginx-home + securityContext: + runAsUser: 101 + runAsGroup: 101 + + ## InitContainers allows injecting additional initContainers. This is meant to allow doing some changes + ## (permissions, dir tree) on mounted volumes before starting prometheus + initContainers: [] + + ## PortName to use for Prometheus. + ## + portName: "http-web" + + ## ArbitraryFSAccessThroughSMs configures whether configuration based on a service monitor can access arbitrary files + ## on the file system of the Prometheus container e.g. bearer token files. + arbitraryFSAccessThroughSMs: false + + ## OverrideHonorLabels if set to true overrides all user configured honor_labels. If HonorLabels is set in ServiceMonitor + ## or PodMonitor to true, this overrides honor_labels to false. + overrideHonorLabels: false + + ## OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs. + overrideHonorTimestamps: false + + ## When ignoreNamespaceSelectors is set to true, namespaceSelector from all PodMonitor, ServiceMonitor and Probe objects will be ignored, + ## they will only discover targets within the namespace of the PodMonitor, ServiceMonitor and Probe object, + ## and servicemonitors will be installed in the default service namespace. + ## Defaults to false. + ignoreNamespaceSelectors: true + + ## EnforcedNamespaceLabel enforces adding a namespace label of origin for each alert and metric that is user created. + ## The label value will always be the namespace of the object that is being created. + ## Disabled by default + enforcedNamespaceLabel: "" + + ## PrometheusRulesExcludedFromEnforce - list of prometheus rules to be excluded from enforcing of adding namespace labels. + ## Works only if enforcedNamespaceLabel set to true. Make sure both ruleNamespace and ruleName are set for each pair + ## Deprecated, use `excludedFromEnforcement` instead + prometheusRulesExcludedFromEnforce: [] + + ## ExcludedFromEnforcement - list of object references to PodMonitor, ServiceMonitor, Probe and PrometheusRule objects + ## to be excluded from enforcing a namespace label of origin. + ## Works only if enforcedNamespaceLabel set to true. + ## See https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#objectreference + excludedFromEnforcement: [] + + ## QueryLogFile specifies the file to which PromQL queries are logged. Note that this location must be writable, + ## and can be persisted using an attached volume. Alternatively, the location can be set to a stdout location such + ## as /dev/stdout to log querie information to the default Prometheus log stream. This is only available in versions + ## of Prometheus >= 2.16.0. For more details, see the Prometheus docs (https://prometheus.io/docs/guides/query-log/) + queryLogFile: false + + # Use to set global sample_limit for Prometheus. This act as default SampleLimit for ServiceMonitor or/and PodMonitor. + # Set to 'false' to disable global sample_limit. or set to a number to override the default value. + sampleLimit: false + + # EnforcedKeepDroppedTargetsLimit defines on the number of targets dropped by relabeling that will be kept in memory. + # The value overrides any spec.keepDroppedTargets set by ServiceMonitor, PodMonitor, Probe objects unless spec.keepDroppedTargets + # is greater than zero and less than spec.enforcedKeepDroppedTargets. 0 means no limit. + enforcedKeepDroppedTargets: 0 + + ## EnforcedSampleLimit defines global limit on number of scraped samples that will be accepted. This overrides any SampleLimit + ## set per ServiceMonitor or/and PodMonitor. It is meant to be used by admins to enforce the SampleLimit to keep overall + ## number of samples/series under the desired limit. Note that if SampleLimit is lower that value will be taken instead. + enforcedSampleLimit: false + + ## EnforcedTargetLimit defines a global limit on the number of scraped targets. This overrides any TargetLimit set + ## per ServiceMonitor or/and PodMonitor. It is meant to be used by admins to enforce the TargetLimit to keep the overall + ## number of targets under the desired limit. Note that if TargetLimit is lower, that value will be taken instead, except + ## if either value is zero, in which case the non-zero value will be used. If both values are zero, no limit is enforced. + enforcedTargetLimit: false + + + ## Per-scrape limit on number of labels that will be accepted for a sample. If more than this number of labels are present + ## post metric-relabeling, the entire scrape will be treated as failed. 0 means no limit. Only valid in Prometheus versions + ## 2.27.0 and newer. + enforcedLabelLimit: false + + ## Per-scrape limit on length of labels name that will be accepted for a sample. If a label name is longer than this number + ## post metric-relabeling, the entire scrape will be treated as failed. 0 means no limit. Only valid in Prometheus versions + ## 2.27.0 and newer. + enforcedLabelNameLengthLimit: false + + ## Per-scrape limit on length of labels value that will be accepted for a sample. If a label value is longer than this + ## number post metric-relabeling, the entire scrape will be treated as failed. 0 means no limit. Only valid in Prometheus + ## versions 2.27.0 and newer. + enforcedLabelValueLengthLimit: false + + ## AllowOverlappingBlocks enables vertical compaction and vertical query merge in Prometheus. This is still experimental + ## in Prometheus so it may change in any upcoming release. + allowOverlappingBlocks: false + + ## Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to + ## be considered available. Defaults to 0 (pod will be considered available as soon as it is ready). + minReadySeconds: 0 + + # Required for use in managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico), + # because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working + # Use the host's network namespace if true. Make sure to understand the security implications if you want to enable it. + # When hostNetwork is enabled, this will set dnsPolicy to ClusterFirstWithHostNet automatically. + hostNetwork: false + + # HostAlias holds the mapping between IP and hostnames that will be injected + # as an entry in the pod’s hosts file. + hostAliases: [] + # - ip: 10.10.0.100 + # hostnames: + # - a1.app.local + # - b1.app.local + + ## TracingConfig configures tracing in Prometheus. + ## See https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#prometheustracingconfig + tracingConfig: {} + + ## Additional configuration which is not covered by the properties above. (passed through tpl) + additionalConfig: {} + + ## Additional configuration which is not covered by the properties above. + ## Useful, if you need advanced templating inside alertmanagerSpec. + ## Otherwise, use prometheus.prometheusSpec.additionalConfig (passed through tpl) + additionalConfigString: "" + + ## Defines the maximum time that the `prometheus` container's startup probe + ## will wait before being considered failed. The startup probe will return + ## success after the WAL replay is complete. If set, the value should be + ## greater than 60 (seconds). Otherwise it will be equal to 900 seconds (15 + ## minutes). + maximumStartupDurationSeconds: 0 + + additionalRulesForClusterRole: [] + # - apiGroups: [ "" ] + # resources: + # - nodes/proxy + # verbs: [ "get", "list", "watch" ] + + additionalServiceMonitors: [] + ## Name of the ServiceMonitor to create + ## + # - name: "" + + ## Additional labels to set used for the ServiceMonitorSelector. Together with standard labels from + ## the chart + ## + # additionalLabels: {} + + ## Service label for use in assembling a job name of the form

M2v z0^%+KXi&e6J$b4H^=yH7j3ohoL?MHIjHPxpxcq;Ny7R(@$bcGu<^&5WxIZXh0JL1&X{7KpfO8*R$0Z1Z6QkZ;1Sytw&@I|S&nkoky0gx28JAp%Q6VV2hx1kqK- z(b?~~=z$onLdeAhd@wXNo#10Rr@RC0#2Awg3zJPxt}=2@6JDePfJWHOb}LZ%LLf+j zfwl?KgzZ2-1|gfikMyG^lbL=rPs|@ z!_(!I?V84y$LC{(P}_;xr4~wAw0*;>IS%iIo7)2A8kui#PmOyc60}sQR1mnZ{;7rj zn?01Cm=qDzsgVo^*8)WWf{+dZ!u88GPw1UIWUYTG}GRI;MNBa3jh2Y4vtnQ7=}N*!;P%A*g!OX zIOMHwEYI_{>|QW8b1WjvE)L-&`8uhO;$H3+h{LGb)N7$WJV6vnML>8ZGJC)*(5|NQ zjdgFh`6>YpA0NMm#>+R)FAaQN7cueW6=7q@{JH_9e)D*ImjtBzx?mwA^z-fGXCfTl z0L)sor4_@=xfR2_x&g-)2sfl^rZYpx)zel4j|8J&_@9s&>kGY*48LxIhY=$eDSVTt zU{-tGjE&jzkDs7I&ylbC=$*xR>LUlXT(zoD5^8xP@}1qE*aAtOicmYeXCrlo)l+OpF)BZ$$@E;F$8&T?Aa;Dwhg~R$5wHzww1y$_gz>TxoB2N{ZGlx4F zEp01;vF2_1|9-29Y&}#sM7c!vSL*tr5du+Y`)Z%|MdOS>h!+yu@Li40*(i%Wb~rH= z+emA)d~+`Jc?qlPP8Au5H|jU<)@_4$_DH=bC>U7~MeGYj6oU55UKAqOc=!>%*|h=o zJloL%4jn7N5g-5}ZG#pD8fE1Bu-Yq1Q1BGI!!Np{?B#qZz~%u>`}w4Udq1vMbKWr5 z3qRnjGgV#J?%!-%sQ%p1)zA1=^$4S18(5(J>=i1Ax=j1t7UJF5f20ky%Cdz}=rgiC z=M!mlj(M#5#ZdXmDBuI}9ShO0>v|dXE2ckp(DxAzv(1|BJ+cud5+?PfE27kC=(DAL&8t5M?ziWsJ$Pw;ou}1$Y4+T!Fr3}_ zqgQ^n`7&BS=ZrDMuniX;y9k28TnK#x^Ss6s8z3`@{!RNidWl-GFXW{=nbdbvFM)ew zBIY}&xN?7u{|LW>iG2%#$#Nc_RvECfn*c2-9odvlFGEfp?=rEc`se<&ZS5fi!#iM`&gkG<)mc7^k%y%Vf zE&|??R-#7~qztvWbJUbe_poW00b8Uc^c|~)+kl6ikO0U@6s&kb{#{+rPxJP`#qc>t z8{EX{LPk(q4PCD>s*~lSa@5NA_kJh=S&}0u3;{_rr<#Z7#RYPY}CX2jkjw=sWk{cs(l*m0bbr1{MX3dCd|Xv#@bUH^5fsvW3~%gV73sXC-xGS zsld%O+`k(V9RK(NV)ad(L1c{~Dcxun6`i<0zxTay(r>*4kJ=ZhZAE@i%)=h?|iRh2$P4_>v(9tf)AS)up?xFH(`nt`)a`X?Y>d`G zKmt^ZIQTxL?Xd-ewuMrmGX26H(eK-CISJ(8Bc4yg%D@)c6=e+gj%SD5j;(dfDjALh zaUsVI_O0dwg`Rg9SeBH9y~x^4_Ez@CEWu;=M?--vg7-(aClB8R;gkIAHCXOrnE6PY zEq)%{kKcrvwurADAtI^PMy$(&GHm?{nMk%fZuh^F`VpwhN<3e6QH`X9_+XkCiVd;$+iMMh8y-=^H6-uWh$Zd_{G|&sl_A1iy{j)}SV{(+G-mic=R>&;MkW@=B~7{aCmNY4 zpV}K%PU~k%NtsW?^Z~sI50X`$2j~+Aoa`QoelN~PKSM1Wfa*Ax)CWmEym4uO_WOo| zz?NkiL0%`})XG=ZDGatYcqBlxuHeKM0)GePLU#t`^7=t)kP$QF1>DR`m>%@H?E z<*YJHNhb#UC{!pC?VQI~rqRl6(vz#QNg*-YQ@ygK;wV=5sbIl4%Y9CwSn zo%tuR%GI1K40QsQ+cJZCxXxrKG3r%OuoDD6S#$hP9#3YV(GNB{R{wEla3c5B z(!_D|x#brU{X$kgseNO+*ewY1PtbfFe__K?sYg5^@robGTvS_p6*L1uf;t&^32|+F zoV?mYya{@oBWT3m*$RqGn3odMSGiZS`r`^!w3MuCrEM>NoF%UD{QlvAdr+_G`r5`L zXjN1?+e}A3Zbf!;Gilm@lS8#+K|WODu#90&mzf5NQjg5Ara$TTnfpwq&Gs}^6Pk!N zcDvIf3|?A^M#{{Z%?({Vdf?N9T>^1e+3;Ap+OaFC)%| z3JU6wQqFdlHNsa6QoyJsL=Taw9=Th1EQO_Bx#R_G^kd}C|0bz$HR%4GU7XnQr^iX{ zOUI!o#K*0xoUlV5xbER*+i}q6X!YSP!PdFs9NO0x95#pv*yb=kyq|o#ZfnS-ZX34& z8k7U8cB58_QN_@KT9X!8gfn2UQgDj5TeWqAhlHT%rhQp(;-N@t!-CE?lG~uxgn2?v zsjvtJkvWqH3Q;y}7RIu%1WklYIBI`3Y?AkU3eiKB`M;O+Ah7$X?nMz zS)?8uCTV0q+pU);9w&*Z){by@g}Jel34QLCC+^;IAqFAQ=9}pzoTxI4;Ba%+=nK;> zUWurg`dM|pVDa0*3T+ebu~c1oDjjbJe7HZW0tl{;FaqVK>icg_nNSY$#Nc)xxmR~E z{9Ks~Stp0a^F!!eX|FNi0$uB=3Mb=~U&t@w__R|w?=V6sV@bg~jqx-~nW45}DM%Hd z*qQVK{vQv^`dL?7oQ#ZpTVH;co<{{P;yNoh37g!ZzGDyi&PJ>?HhYOi%isuYDUR%X zbLOXNRoS4UScTovd+Hl9Dg5rkFlOy?aA*8XRj!FWfA&_*GP{6zhFrxW$0mB%|k4nNoL`&JfQ#^WP zQjyc-#Z&ktuoliJFO0{(1j|unE(ioJm3jIY{cO;~e3Xsg`Oxce_nB|0YM3jvZ-I4R zEbi!9A>;(zeMcps zraZ)Y`Hfoi77afGew0X)^CVa0LW+9z`j@DZyXjPQa^a&cRlzd zdo4Gm9yE{hiS#vhQYA=1+bGTvJ2nLRJhF4#)(hvjW^6IjBhiD}_4P z=~Dz5H7$7Shel08cDdy!`%`4-LRYe_Fz?ecC#JAz&mx|h`fmpz)N$@ikDbkgNg z1YTWj_{^DV=Z1|REVqw%okQwUF=-+8Dw_R+)#ddiY$1Z{SO^`)m zD=?|R)06$1Lf#R=y!EDhv7=W;`tXV8B~FQTcK6$qCT0m^*GA1<#lf)eM2Y&-I=X1U zh>R|CNO#&F%)KFGewuEqE?1A->O)VqnV+5nQ+F1*C1N(=p1B)s95js0#oqHrZ43Mr zI^fmZc`VFRFZ*rQ(~`~t9b4J1+=MqR>?V0K_jE)ZiT1-<>0KcKAUF+-GS-v1<5rW^ z%pJq$ASWe{Q?vQH!H<;pbF;0wRHcp`$8)V+A{u*-FefE;)9tOkCl`J%R-HeSXQw)> z@SwB?zKPloQPVX%PjLl85~lAj5BW+kzTm! zE|TVMOd`C)9tsPTz_>+*4FL-cG+r=Ro!vzB1GUt%cgQh+i-PK3j%7i_j~YIfM=>T* zKNSg01p~j(@@gq~llh~aNc$t|ACRrL(3}zE1LFH{APZ9$Z1YVU0gm#&NERHYs!k?s z)|QwML3cmkWYNb1XcQhfU7q(w|Kr(oEUnJI<3}*y$WJ@`%3M7-z49m;5(zZEcZo3j>X_EhBpl}zNsIM>x(7#O>ko-A!J#2gdZrvbY{_2H7$aUhumrhH z9qfzyEn8e3PA;7_o|h zF_N>TKzaP-H!|uT*d*Ep36)l%N_hH{2lEH!0q_bvynM32%IEaq^)bU7}+h1lvziP zQ~5~>x90fYxc(Bth>wpBxex)TZ`3r6oA8x71=5)Ts^KEpe}4^dxS*dj5c}iEjUY=t z91dXwD#lJdvSSPXo{I;FLiomXoij+hbE~(H6=7cQcL3&h<0f*^$pY{# zlN$I@A?0U`Ek4(oBtd0`Ks5p2;KvH#E3-^BFrVOV{5~Er2Mj(FhY(lI6_;h zn9Y(butFpL44RLc(`R{HtjcR8fjM@EG;^Qvz7_DFBfgo7uHikt`rf&C{1Lp&$zK7C zRQcbSUt!FuJ~ENL1>g3FuY9H(|J0y}BBh7#HWh8IaY{AKfGd-D;Yh^t%JOa9dGa*D(zvcEy( zCEN+51QyfN6$vjkVUrn_FEMfJ&u^X6G@WT~bTSTor`xUW@&Ckp=X2!AKuPO-vFq=zWQ++O;%NC@-}R5cd!qHmsB+#N!XE3y#o7wlSnF` zW};|zwHnT52;6tVdGCi19XPC1V4Rz8_C$;Zu1SOhL5$l^5ln2fUd`=0Um?N?sSFv= z6JBf=a!ffK3y6ehoMuD+h52sNa@9Sdbw>V{6hk>xix8makjP2TEpQNM9|VT&$6o5m z)TP6(4AlPyeUYP#1T)n4ghm1jj){B&qqOop>T&W~IUm2$NYu4GVw-fyd}B??{Dmt* z;0l*4>OFyO+L!{t;42+5nHp@`R4K*;}x^C_+ur8{K=59AxbPh&Xez;Ce0 zt9v^Hxwjhh5p#eQ^v@s@d%X9m|WP%SKb53iF$KR^;>6b>5dMOtBSB{ z`8|=o1ih-Q#E)Oc`BG^Sh|r(zO7Lokc9m=`srKDRs9lO8 z;ex4f#`vGDRCOQMBRGe)=!Yqv8mLE+YPL8>mf0nadJF}Q1RiEwj6Krgp#1RnEM-S< z_b|&X7L_G+das=t4nOPkZZrwcRtIDG#@c{GlW_C))p4iZzuLCL+S%Vcb~A4&Pwo>i zi7+?ii8q%3kVlWcTPRP=(5wUm`s@clyaIV*zZE6oPrVW( ze*o$^nG2?f?Dtz&QmPkJh;4g``J{5YWM}9{E7i!USDj~*YB;9NtCE<|_vpG|MnD3I zUPBg&!JSkX`dcWIwAlsCT>DGT?zAP3kxksyPn1T`o{&@SBqt-LS1VAicT`kqbDve# z=hjBbSp1Phr={a1tyAwTSO|ohB08_>`Fyp$`*=G%Ab)<_n&H3VOJ<8t z$l~(lc-x&bqMvzQ!r=%_F={`r0mO>5m6eBz+$lF6Ar-uJ;gk}^o9`h>$wT3%UmwPA z1*CFe>-=x$H*AXITLOacI^_K&Y6BM)1<8H>epanUlQ>n8Ys+FM9MgAmgI~%kj9$5? zYWOGi^tR4_D03Eej`s(f>Cc{5PGZ{CT6pnXUrW077LttD>@Y#Ro?m>mU#j4~M30{( zk76H=?w49Pby?r<;D1eJKyFO>$9?s7?YG9`eVJb>Jb5wI{+MlHWAqUIQguVhllU?{ zf1cMaAj}ddY8jc%T2Ip_iTX(BgAx2tap>z&wxY*)=WV$h(p*cm9x!TU)5nR;ssWy$oyl|?XZ!2iNtr2TutyGL3?zkB7gGP7gx#IW}v+r@O7We9Bk^oIgctqzg5AEDTi+?)7 z;7iY~q}X}aB({H2?b9@!>PO43>O}WkuJw>)o`K?4Yx76wf z9(bQuUA0HyZI;ua*gogsexa<CF_*#S#^mWvZ{B+CIyos#R|PeK(J3ibLVX=hbk z!-Fh$GwO1??J;syyWO$S-*)>Ms5PA#lxfwS1?Ci*uF47wWp2g_40@iirt$sj1zsD9xk49z3Nl*9 zA4J<4$JxbLcgoKqoW{znBkLvScZE338OqkP4>){8-zyFU$Hm+-ze>@x(tx;sgGEpX zu>luCC#Yzk5~0kcNd#D63QYx|IW54Aw!=m2eqd&TQKK%9MNkNv%`3$IVTZo`MK(IW z_5t(O;liIdt8D>zi#!R0xs-&7{s>6+lo0-9o@Vp$F_M7n_4WLxQQoEQcEy0FGksj> zIJX=T%#d{{hLIxr=Xc89bXlts(wMP*4h*A8H5I0ZtbA*oX?h$eTK#GI`AgH&35xFc z^Tbjv9yTn+y(*S&>6Jrl1ywit7dvr?1wXDgd@MTJ90XX1!&I9xL0NF1S;O8a9R%8* zAw7Pm^j}3VA+d@=;m?UN()ha-RCQ}R+3ed|thvtggXA%eKatZUbQ<#5cjqIl)sfOR zpO+J?g-<<&s%=2^j2U9v>O*F5O)Mr=eK=6mJoD@gj+a)L&>2kJ_F%$JK|x>PL_8(( zVLlE;%H5gnm$-rqTxl`6nr4VfpUtYApoGP}Y7~e|N9`}L`lTts2Z{K+RpMY&wxSt9 zkHp)ive6P^$Gx`s6^i0v`Q{vfE%nEx0)tkjvoU7V>bnQ`K-gD8_!xaPgg$Bkkpq|q z>_C>flxe7MTyZ+hkI=xO7&W^B_2%a9pP(0|-BLaN8`<7&FM(zR;~~An8IVP5h)ab8 zCgGm!4@`_zW#KAn%7~d>vx~t(uVbZ<_)enEh@qWqPl|corPu{}3y7vhnSP_r%lE;> zgl;|DXY+_M_D^T|9&L{Pof8m`bIuaItjXTfP#;-MN0YF7HOYMDmF&l~!ZF!8A`9ww z^O@b!rtH2&C$w_<(7)V=oh2lB7wJ;X>Ns|UK^c+?ew9^n3(J{C63CgVLRr&Ph`g3% zH87-*e>R(u9HQ_;Qix0?nc>qI!TwNTM=vOY`m~?{v7iwF90X$imdlnIJ*yLPNW!uI z{pSf(L4Gl*SbQ-lO$a;wcjAx5Db2Jv4X+OUT=pv}a+kX}cF3Tm2+DmAf*55DvzshO z2w1a{bcROC(cm5;912_G91MSxCn-6+Z#B`LEL?ic91@+!g#t!YHeSyNZ(-NbaGrs% z*pDMJ7@H1`qakXQgKg$vJLGuiqV7Ime))r5+`sbbeF$%>#~3dsk9u5n}{voNW4o+OQH5^>-nw6@+p zOZINU(h9lgadQGngSyPqpCPZ zhEZ|oR<7FZEka_GGQc(VBOTyWmsszYisjBGXS3^Fd2Nko0xah3?gnC{%NtJ~5=+$K zBY=!j0Fd16^{N>@2Nw^;%TzXANGoZ;>VUDMw?^q@f!#gB(7++Pbh4*@JT0zp@^#5- zflJkO=>$lQCtr*TX0GHH)Hvp5HG7cZ;J4qQBgmwnSzov6PkL1#e ztnqw`FGsw$s@qj~nGH-EdN>TcEqn0*2IFQ@xM$vKP0({vMvWx7ZwYMWRre~N013g! z`h{5!Uuf)Nbf>2LOs~Y_?9))OVMwYh)Uim3&@uI+UF6!CXV}wjg4KevqbP_ya)kT@?2a(%;8WpoKY5TW(WB zT4^-ngduN0IEaWc9TNZI@R#Db5*32U7t5)~?5`hJeL)=0)WrC8f^lCz0xf5sdnOgC z(!~cqnqzkyRstzUd_C4rL>Bp*+RaAzniaAe2pZ$2{=snDY!5fNzZiZZ|C{!s)9WEh zWGk2G&wWHZcEJi^%fg2}z;2hfn`s8iQkyt!^4-lhla6Gw{B~i6R=C7}ud~A`yTBIj z&Hq_qnR(~0g2=&mNX59#@ieInui+i`DJ-69jtW-PGnu44O-B)$X9cL6^Whrh-nfK5^% zSpSFM{std|w{X9YwRk`vu4bChNy?tXhz^z%f{)75WbHxm;pc%4m zOJ1LDv2*OBW)0OspU`IwV#?Ae`LEyJis^cK4l=zJu-F;&e^J~BHxs7GueZ&|EGx}v z+-Fw!m7Wh|)?FxgmfSnn_KNXehP!;#jLiqJMaXD}@O_X6@GmGVe{WRWh}2a!c;VR8 zgD}jEOnF3ufCZ84VBE89oVRK2R-#X+ z_^pBMUQxK=*`s%$$>!cxeR0!B?f+=Ne}alUSjLhp9~eM%3dE#&2JKh{Ff!j>+d8Zt z_z!K4Sg`fG_gdhLEf-v&4tGuW-vx(5_Kw!fI;-l4{&xeOTMc&RB_^wU%{r9Mvz{!R zOSg)x6B@fv;MdbBbQ=~E9VnYo!<>*_?cI;{llF6xTtrd@X_p2q)lRV;K>!yR6bWeUbV5irXS~K@FUmlf>V6?gMx@9k|hf?v+7h9H#_&iMIWUuS;G18(; zHSR_(CsY>iB3>{mc^AnhDsMI==P+Hq+<#UrbY6fA1WjgJ<~%#4u~&rIBCy;XN0$+f znDH*W%S7q*M@(`X)g>+wc&`#L%wI2@rv3JZ+VaA`Z=56asoMuYBhpRL&Ix|jo4tm8ZI`%v_P9D3*d(q%v zJ%o0@c+V@mPRcG_q}TSi*9B}UlL8IT$2gN_^*EDOOci}LnW_k8X~-oq`Nr@dV%$vo zN3YhPt9Xu1Uwy-7f=I?QqP=q$0)exY$ZTL$kivo@800N70mFjEzkz`Zw|57Q>RG9U zNR>2C*hr?Fmm?a9Dv?k0nrw8%+V9Hk5P1tGk zHG!vKegTG90V8^bY% z=t>K{+rmp8pJ3`UyFr+gr!N z_T7zy4(04UU2}@`L2^lKziC*Cbb0eJmKGEqdzzGf%jt?St{*`9-a_RO*fBH)md_c( zF2XpD9x41;Kjy7Uy^OYS^WKlsU#v-c+y|JW6IyIg) zG+n9Q+d?zX*Kga2vlkUQoUntt`0k2ZtKv**L5(ziom=1#aB0KoR4Yi(YJy%La#eK2 zXbduc(*kIyxY(h*>g8i;yzFa*WQA3&fZghry`}9+Ydl5=#<4eMABPaJyJm;vU@YZk zn!6jtTUq;vIp`R`OSk);zd@>p^5RrDhAG#bY*H|mrZi?Q)g7Q~t{+gW4@NQ*5#Mxq~8Et!@KmgzmWF7xuUEiLFCfeAd*+tcdO^snJTShNt}CNz(y zA$<6qyHHKGUv-Z) zd0n?I<%&OEn@;FabYAQgDTyb=A#%X_dhhFWjb0j@-IU1d{sLnrglCps+o$nuI6AP} z9H-stSSv9!thy)>r+qq_kMY$w)90cX;QiFXZiS;I|U(O7ftXIS!(Bw}inE81NC149B;UpN6G0bl?8YmI9oRuP2p4%7= z(2-acWF8Ml4&{Bp?hX19hI}0a!0}=Nd-#4(I681Z^5B41fB#zou|3kR;5;t*c&&fp znmRy4J?l5{HEuwuB}|h93q^BN>&&a^hxq^=Mk-?vmI z+Z5*h8t59T(F1;9DZL;0-jH?>p`O^5n<*O(`j`C5ElJuA8g=8p;*dUEEa4)KH2%1N?hdlvfb71}&KA;)-Vg>A(1&hea5 z@CWHj{l@BBwH_8sT~}uf9kTE5d+J%z;tD3;m#m`xQK;9lf2#hiP>oV;{ZMk{78iE$ z0z5|;HNL)sRKew~b5x0=889V&nkAcI8@y#YE5KrxY;cYeReNyT+=~~_)XMIhRX;Z! zL~cHY+SA{hRa2*8?2!B<^|9u@<2c=lw#Bygchsm-H*%bd8xluNYh6I?aTBvw2(j-t zG^&z8KS1msL30O%w{_dEfo-o}_IR%e>YyEkaCPW3 zIrb>@?K0jE?zeXeGX5N>ziM9mH9BtElb+L&qdpvYbHe6h(ne=1ZMKX@I|Rsezu7jBbDd!Muo3uo@UH32VJ@JOL> z^Xi9xwzMkObNOzNto*&NL2r#0!|;%1$hWiF2tFx1xee){X4Y(B?6r+2Ddw19keecB z5@xhGZvHeBIRH!!zmVpdpTt(vein#t1D~t29N}GlTYUJrkMZ7=762>9d!WI1q&ZF@ zZ1gm~vKi8sPlR~lcWp++4mpk?p)=`Z)75q&P#%+kLcX8`(A!jRD90)Ct!?}x*q>#{t!828%$1tux)sW9&mX%|4xbRehS3@s41mH{hTwkI zKEzu@C>1Ora;44C-6+YgE+KyF36%tTMX*3>H|c6{z1n?4F5qYv3zWGuPyP5`R)^?+ zusX^PbhZ8%$r+_gnI#pSPJU=8m7LrIL2%Iza<|qYRM%Z)2gB~hUqAE1A@B_vz==*H z0!5^4`{>7j#*L%2IK4dcN;&1Sa_6oJYl7XCtY453=nV=K(Q-2YzdgP?PG|DeVEtY zVpy5z{Mw<{{{2MXWYT1Rn(}8nlBCOLorLcZlpTNmD%&%;%So_4Sf6~?#-hDVGgF#e zm9}E)^+T!yXH(hFgaD25i)Yd`S&n7_Pf0*hf`OIUH=uBXWF8hU0!d_Ay?jo-+C}Rn zHV0;in4xk6$GwWAoDi`CF%LEpHz#rf?!-!7XBYsw5H0d86~lIzN_r8uz@%X)(=Ba; z{av^Z>r&u_a8!R-1JM+0fi#83MuQ-1YPqF@UDMEW_4bi(bxG}cn|8V4e6!Q=cubAH zNWfnx>3wezpL?`Ye{iVz9Npb+Y)@>YE-D6(EK@&=RHvdOI_UYMDRIu`Dx9w=EIjWhNbH?ejR1)VhC#q*sgC#%oLvizABWzm@flCMnL$ejP@*^z z{Cf@4*kVvG!Bb^$b0I>P^f8f+&4@8&F~V2Rgb}$ToKNHm^T|~o!)AG{y~*LtyPCzz zyhTOP*cGs8wGW^EvuU{kq6zZZGL1=G-sN4pst<@M{mIX?bu<%UhT*Wh&SxH{n%&Nd1NunZ-&?@=3+2@GdCgi3I0O^ z`va~_U8JRH`CG%SZ{aK=|Kut9byXBwbVHoFu}nS`H5Sc4!*1HLjS+hz9TC9y`krtUI)|G8>Dz3~(u4!>vq;d=J z&kdH_F!RSS14kQ(^zo#F(hxSDGQ8(LO3KnyOVbM1=E%td&Ggvrls+vEi-@{F`2e4C zGd(o{&#PPVge^ZOo()tD@VFq(Ragx&foaD?SPhC2I|c(RF(e*ok@}tkgY6u`4)O8y z5ScQf`QJcp-UbHz2?#z}b138nzFza%Rx*pYyY5-V_ypeLzbb07sn8cob?=X9DRZH{ zmj7y)ufb^HcykFbehT#Wj7~Ff0=-s(EJa|&}7#(a0no!GGs(KaKpQC*4 zu_UnlIO3P86HDSh0ChTRMy{q$FGh`@F8~2k=xJ%mmJNwBZOz4)=o9F$nJ5&})py7I z2b+tk5f{Tk?*)i$_X`+tGf;byg3Ks?=f|jdXIgwORZPjM=KJ*!}aib95$!vFAuu~~YA^!yW`=z&tf=>*6=;kp4 z`XXBB@f=!cF;%YdM7LN}&(q?g? z8YdboC$jqqnEcbVK}E_^KQ>(Yiw_QEu$(4CR63P?_zJo3Y5i8ENxoAcI!*ClX&@g^ zhRZSpl;KXy|6PVV@jY(u`PHRr=W%)xk!ZHK5Z->TS}cT!2ox_Az0712ON}Q?*er5R zggc)KIxv=!7j#ENXq8NbI6L8ZL_YANn^;&)4ks^RL!n{)ifGGJBNK)Q{cs z(!W0@XQjC(R5qXhso#rF*Qu{+&IX;P(M4CN3hJt*!Q(@WNGW{L(mJ1DjZfNF6-Owm zn&%+Q{MwKXDMa#>jv_j2Z|3$RG~G_oyez@N$CkQIA0W*dg#;ML(?D-O=OYqCHjN~l zkC~eync1JrnxAtpmQ~X$Ci8{levr!;?u#w=Xon*92K zWrX89=hXk7l#L_2#6KmbqYr<^W>dbOXd}B`}6%{T}MQZeWec8P--?${^(N*m_jQ0I=n(#Fa}2-oNH8KG0sMg(sb;wFAbg_GNl z`DNmyZ$Ok)_qfyR5HYlyKk^3ShM5%YZO<*LMsYU0&0zZ|{&%@syM7I%+?F-8&F0~Bxk5uU5-Zd^;=CrC-6nIW zTB#r|UXiusIV5&-!N%|p!!H|)tO30q`&f-B3V*fGz{P-mijCNI}e_r2u2L8xKZVn`Mri5}NZ zqC+z|Uvjm*K`zdM?bq_T$E@7sxQ88`f3u}Ger5qe0B0cgN`_Vz{{vn*M~#HDlf@A@-Z=2Z=c85-^LuRSs{ zYZ{gEmCYHy^~)Ckl_PZ2af#BfYRx2HU(Y(k4i`2uhN+|3;VxHCjs_<B{9+nHSe{vop{7Q3gQpzJ^hrGn<}AJXJ;nGg#vv-}Vw|Uq8yY*eqIl+9W$ZE&zEXXRe`< zoOc`yiy)@ksA(4j9+9=rdr-bdZiV^U;A5m1>d2tLXbC!oMmdtaDQO$X@3%LTXEl0} zNgy)g9?xJ5zKOzVlr+vK4Z+{u?#kZobbX%T1j6e~lcntELKTecfo2(e{)F0>;7uiy zy*Sm2)Bw*;dn>FJ9}H^%L{?rgMD<1)sI6|SHG4I>d4Z#C*{|WII}+;ZDyu|F$Ywmy zb}$~bt~ayf+4+UsKlOY_>TtcdVh0iAGrKp&gZmd-{%#jr`aeG^L^^G{KdO$FftPsr z9d0!Ed!frSbyQY87r5iBXkderF!wAwM#+tBL@`%F%6-|d@+Q)xgg#i8j;?4PG@TWT zj534Aowq%kKGTYsX=*Y>+v*sLceqz;%l%YX_xB(Rh6q<)^dA65SX z7aS4yosY39bx%LlxpN4O8+T%gLQm*BR(1M8?mBg<1@SW;BZYe+_J*(OdQ$Eu1C&}F zcf3Teof+AcpWwT`PK&BnVU*Q|v_hpNxO)#T!!69xX^cB#($jPa?36bnjMb+0Js-=} zl8VH&k5nk9} zYF9n0X3ziFCNNl$!SY^^Q^6^7_z$y?z(oV4` zQ~e4Veq#G2vsxp6N)i6j-E~X9unt*lN;_N20rGPe5wx^fm{XLS2?v%T4n57ghvQBL z8?!5qv3f#>;;k*ON14*gB<|Hqkns4!2e6#5Ui9()SI*)cgaPDimVWgU_`1?0*6kV% zZPHt^USqTD2O3NybVQm$Q`GWm|DU7K+{jGbqrN?t5t<~rJayjW1hH7JyDi$Eb8fS8 zZ`b}fx#ox)XKJ&r6PRDaqE$UU1)?PnX^e*NJz3BG?(bi5%Qhbe(Ia0ldxVHX%K?0s z^E#niDzF7Z;d^#oMs!rdR?LkAHj;?*hZ}MV5#Xw$yN@-lN>a3tmgl0k>QXL}GH&LdYxB64B*9;h+7+uM_d@Waqd?=P z^3(8Y&p2y)$RgjmTcJJ^v@x{lx@s@lip4^n_jdoBx_s6*MnS*T$|#- z*dQ8TL|43o7zm!sg)+jBLUnvx!`l1;OHo_!Y}Xtl+~be*3BwaYlT0oI!2u=*E`+0P zR(f1i`SS}HrD0VXY8_p*#kn(S8k)D7-^cz+{A@~7y&_htJ?PK1C^Ms$t^B@=-_4v= zQrVO{CsKz`@T2(Iv}No;;Zjb}7&nOiRm~w)B8W5f-SLdLks)O5@VbVB16J$x=Z8;- zSdq`|Ypk++Qt{xF^u0|-6hWtUll<+)@ovL|v_Xn*R$B-+k&ll|6ZoYItDZFF*+sRz zA>n$kyMYHHj$RCKo5D8?HY0%2y&ZK9M*6BtOuInF3OyGP((h_xNvwFQk0-M)ewcZ@ zEz`HWqG142F5C!oXt0KzF2h}`QaNSEVoY&qfkxpkS76@iej5d)E`LF%oKnMyYkQ_D zl{M<|>`ZTwmMk=fr5HNEqa65s;F(EQzmwNpkrGuBvd1iLJoJcsxZR)dA-1CMgLbtL zjX&`c!;cDndknws&dJ`~G?D#Sdm}%wL_T;r1^_tsH(H^H_dC9^9N$Gntr^;v@?Pg% zsS2&!@i41a;*vMQs`1+r3a*TU+t8J>-_mIGxCc<->kvaI2DiLWLOt zcljw3rd)J_GJmXp&UI{~nWnTa^h3=lSvfb14Ks;rtxHQkuQPMb%F=OzJd7cy#h4Z~YBVyEosf7f=B9zIhhO^m36mQ^GaU zdj*~{4BH8Xz5=sF2+bUl8hjxS<>zv9cULCNpOXy*{8%h0`A+6~a(5?L^}IXv`z0Kd zpb*OIJu&CcCDtP5t$^-=EP3_NksF%$9#(wTZN+ls*anzBx<7=tcjuY8T~=+mJaX^M z>g-lwD?v>E2;)z5{EBa46tPKu$+uM|GGGC)dH0Pu$m-Qh0Mq? zp#h6#JAz=@1PTDQ-(V~|)c?vUe72a+zS3_jidM zN4Xw61oE15JcL2QPius57`nn978`=Vc%GlN1S^?TuxF~+sGL&04GWk^@Zwhmp*y=t-7M$$R|9~NLxm^S`!eD&OB1x# zl={Xn0(6x3ScI+*Bh8pIh~`E^H_)vXdL*5!hhO3C8uUS|@Y8kBqdx8J;b=?H9pE@NqbVg28ltcD%%tcfn%u87ZhqPj-mpT^L;E+cd`iI2<*zIs{y zZH>c3V*w-TmOH13e|SsOKqR=`zZcJ8oBzqevVMl!rw6LD2?@VU8}L2vNrv$|%d zzTv}pd!l}Y5C4bpZA=KaX0FgLUovVK1?;h5~MzHcD=507KUB5QVT(8Ltqp#k%mN z>?-+;m7cT*XJ+Av6{HJ&-(^0W)x(;lUl}ERbHD9>K_JL&o7=j%oG&k4k07hR$1gnO z#)?rIwZ5=8-nR>roEzFi{h#yaPsUGr!dlRq$BdL@o?{lveK~fPCfBd+^BvrpS&Yr6wtmS=;|=nXB9H_vJ-q7Cn*(T04b< zeP5rVefwX=chG+@zLmy-#&`6 z?b$R)GK?QSXcL+J1Smr8{KjTbODZajoY+z2CYKg#ye$yl?O|21`8aJ(z%lYlC!oBDQxqnq17 zGbsLRCW`s8fD_D9FfaJ$Xf-Xf3}N1k#2IM5wH|d zKi$%#thl%89`DUz-OG>*G`|oSfQ`KwHB=1@M|%E*diyBq;N+LAyH;G`+lr6 z`uavc_%={(GQIoy;OSM(fve=zvn_&W=9Z6$BxgBf?3EVB;+}aW(>aV_txZF+=2_@Y zydK>cqso6o-9NWWdN1NCm!%%&-mEuw3j`;siMa$)xnn{v{~;r;ILa;cuKB0k*;a>rzJbQ=;T0JyF~5?d6Qg8h1R`M8HN8_D04emV$C@kxw4& z@oQmg1I1=tu8Dxil%eh}22R;$xmD{p$OVKKN?tb_MYUn)gv5pg7YZJp3d~8`TQ_DE z4Ta9mqeHfVT#Gc=puV^k6s2gjp=;|-!Wou=;+1}xeBIe=WY(8Mlp0x1vD_s-VEO-C zm;slp^z)f}6{AZVg;@7#CZ2yb_UD_sO4%n(5IDA|tn_x(_LhU!&V9c6Mvsk2i+LFd zMWUyy-tC?2X{MoLm8G0ISa&Acrl=aJXPUH%Gt5%*F=m0=(W5A|4s15eZ5ez7N3tkK zm{qdp>PZtko#(B=MOV4h>?*yy)i}cYecs)2D+RI&r{jj- zH)K&Cu4o^>Vm`L6(}8^B`bk&+Z7=T$Gsqi3vlqxJY)0w+l~qjO?Lew@8^txP1E5(N z7?Ws(INzMedJiHm&1F zy3coRAv6}mU8f26h8V|=ew(~qhsIM1ddph9?+^p7i>PiuGi#Q#D`S`M)3See`Ig9Z zpH3-Z<03UD;IeC47bC(J#^?;0)ZTMNSWgkaPd_W1`OX^h$R|*=;FN8HDLUXLN1Q_h zjXZ!-RO%YCgbL;=vT%X>Yv1NA#u903&2z@XadE+-Af-B& zHAiT_!>W-Ze(rfdtU{)kwe@3sY%yyNFeXyP1)1mw(Y2{Np+E|GsCa0v5!v61s2AN@ zyS+_sx5KlAs@v$ZH@{IxWnYiVvsRrC{p(v*q8C@&lT|0Gn(>wiojxKA!Iq-6Ki5Xo z_t_DT_A||8=*Mk5tj)lX&xZV$XbBr>e7$sV?uAtXVIOKEy7w?qf-VHPf28w~3F8&9 z1h%;s{1UHI)z$V0_?{#)SHku4)d0uSK^K~24}?J}vJLA1;n-89@#bH=H^cT8J_8c< z$%8Flc;ToMmu>Os_N>+I_FEz9Arp5UViI>wZ@6VpXD;Nn79=mLS&5C>2rb2E4NpJT_N+%xO}Cw!?re0a50|_1ivGl#YVwy>uMWY%4-T^RRpBb%)9zh& zU4;#W1Xmtr4n&=)oNYD$hErpmk~sllhJvc3tlv0a$44K}AKuSz$q;|sj~sorzgZE; zld+HUzsNyuC%Xg4|M9hOr?Ct$n}o1IR!8RMN>D+)Jpdry9vV5>Iw|W#b8|F}hmm}* zXB1Fgae%9PIUk?cjZ99HClWB3$xgS_TAso5IyYi~C0H~I%ObkCMJ31Ax}R!H^*aD7iyDqZ zEetE4^ePzU%}lg;H>Eo>Af>3hHVM8{Vl&n5Xa&ZkT)ry_{k%pv1Q&3`%Ht8he}kN% zFDv|OAS;oW!>*beDsa!Zp5bSzIWXt^8J94E!1%9H@lUVsF+02R=S4*LtdQsAMCd@H zrQqZrMhn!!xu3p32V%XxG%BGgBg{>Yg_a;xj~F&f+ys>LG8K`)Q)>*e>3LM6n#=av36rB*#lo)gf_h0GnfWei z9;I+j0&!Sc>NB=ItEFrtD>ghgZL|WI>0eQgfq~{8@s|vRbYs5@%buQ(%2$UsYMo$! zcRUp%t2KlDPHQT_RpK z&-|CbEgI`!A2@Iiw)*cOFv%Zt?Lj+6;)Kq+ zmbgaL@BbJgXoOp!b0-yI-jsJ25*-@Eye2^gzU#88Vw6@T2-7Y%>1=<(9?KHv%kocNzTxt8Wye|@*6WVpq4O>tf$F6OinzL(2}(h0B!iz>U23K7 ziAp2?thQpm|EacSBFXL`v-^T8u7PWOruP#%HwaN!ei369E|Wil&Kxrhv7{=Al7aqb zwKWRwW@lPta`vBzkC3bXnfUnfAIhzgQg3u$E}T66t=$^8p8A3h1&wb&ufvx^0D}DE z@#(UgL!ROBKh|4k4_N4fcsBneJeGR5?}@hBQ9dz%dxe9x{m+C4FOqjo&3@^x|L(U+ zEx`QM(r4P+pe}^a1$n^RXPTCBIFLHJ%9Il;i|F_^oIoMv5H`0U*|!!)bow`UKs5Zr z9fUgn7k79Y`$wGibBeS1YSv$I+8ED5L8QOutOSd*$>z?0Y1&m_n%3PkGW@SJEhaL5 z{4cCelrKEJPVvKEM$w&w1S2SEi{k>*+`g~>F+kMHgVaBgY_ZTmP@o$=_nRiQ1R#tU z`T7#E^^jZD<}+R0WE1aE!jUuO*2e(YY}atO;hV655< z2720S)W1^S@`#v0CYMFvG|w{Ez3S-yyxLUhvaV@TN=;y@dw@$Ew)jEs6UnB;L^QP; zZ+>Ae#df@2|DGt$+CXuP_JACYUdb3+e22NZWGG3j+v7z}#fXGSwsQ(h_Wv(DU3ePP zMXFxn=>SnVxq@<>X5Ti)G~je?`tk=rJCnDHO0%k0i^_ZnnN5VHa2-&Ug~sm~Ya3v! zFkwY{O|wfbZHt~-!vByywrFf+m%INnthGce&MGwP?3!7qN&55KLBb-DFE9op1c!Nsj88;+qlM%K zX{+_&zew75LBujom3Eso7%m`4jYw!6ooOPx<-Af_ksoDNic&@S<0ZSa%0-(xXtsoc zyW^>)^2dc_WWOKYq|safN2rqeC9hc2D(|F1be}4e@Dl6Vv+l` zKUdPr>NMrZ&FZbrh>@1!c?(aGaJ@YBtKO`6F4|C8PA#+@qKule5nwMBZg@pZ zJ#2Ux-SyH`*^uHAXB zFp@Q5nigj1Hr$Tkv;PDxq!<^lF%6NYzJ%q;>yB0aFvf)K2(wJvI~Wl^$Y=GbaA<2Y zkJe@kvhiWq`nT@W+iG3H*QKA=9Pj7kbY9iN7JZLA73{LMPHF5sVCDz}J1NI?@%K?S z;hT>;ovoTnzN5%P%4nZ4*H{%7PuOar)JTIGP*CXk_b3P1(oifC$#mGwv7IA26j2fqRW-yf@B? zlkL1s#mVBiIDG=#shGib*q%OJF5#J@BVWl1L%h#k*yTem8Htri3h_$yEW9SDl>N28 zZ$$K4=yCr^c*xf+s)Y8p&|)9wejws=t`M&k^}Y~mxlWPk;dDJz7=t>|9?a$>b7+xxM8 zRPnG&qL(9Cz>BVFaWb^AYEd2W+cUn#Vf)Kn);`2dv1>*wb+W_&j?MuW{0yj#i)K zUsoCVN+Mc2z8WT9$EZA*uKZM2?t<;zgGKwEch@wQ|LQrSmhhAuc~?6dt2N=PwVS4} zq}$Oe*YP_%6R1&O_-tDsic9|9yv}_|WxtDPsLIB1YkYOppUX3nj-q$S`lyNn3)gqG z4h|Hd`y}<&!oSd(4KYNO*()8Bq;B#%=?Kp6w5)E0_NC2_O&41D(0>X|l=qPJ*;;;A z34)p%aSpV3a0fX76{;eqPn~^0iyV3$7wy98%P)S94P2$5q;+${QZj}n$2zuP8OgG{ zmm{e|OUGC()#IV&B)W>2QHGI9&UdXcf<{GUk7-i5qy_N-O^%A0aD(V?if?aGj;%j` zISl5nsQd7XzUxK3@kiYV07Js`sG3!7+afbmEjNCVs}R_dhn=Trw3b;~3hcFYs}dN` zuo&^#Dmmh1+~LG0PraSI2+~AC2pLbG33LKq%nN?&@ru;zg#tdh=ak|c+cqA=ypbpn) zPw#6Y7&T2}1Fp~lX_SWkgv|&s4AT+)iuaaj=5ME+ww2zaP{_}JJssGq4;@aYN?;@3 zs0;LW=i91ZrUS^unFSP)-31^dPGU2R#34S_nus$CH>M|z66Cw1pF@Xr8$ll_QAUtlOi3qOA(yKA#Vhd*p@g*O-gRo2>I60` zp1Q9(tW6l-q=>Ua(pW9oBT5w@D$+n+ikNegB+Foti9`T0L_90%ld-q^C8jP|3ROjf zoPleSIx$@jy7LyyMfc+J<%39aUlCULyEh%^0b}@XXA)!UD2@omUUg}|W*HbRF0=tVgR)BbEgcWbh5rsQg5|#sAk!x`g~NKB8L=txDrJ$?ebND2%Exd#rfSr?gDQm z`VQ!5KlTh!XiM4`0{q{%S64YF%!G&^w|tHiEZ-A8+xZDoU#ebfz*dG}pf@_#9}{gz zR$aAKxAfS!IA)DYQXH*~6&u|z!wRlzqtN6Liv}oKK_sWbEYu>SAJ&&ILyvv`8JRAO zzsE27^;wvi_i!c+U)-Ld6Y;YI5F`kwU-fC$nPI?cv0LsAiG(tyU9%9Gg<{6^&$l>XC9*i=b$VO0F5S|0EM9m-7* z;KQH;bA}fkcXBwno%m2w^$NYatqr(|rc;j5C)uskCP(Z&p~BDyI-|}7W@XZjiiJ6m zCoPvanri3TT95p2MYj-BoS#~`ziwoP?_UZ#FZul$I|KDBnr;izUKIe;O-We}19!xR ztBKk}fIDJhA?Luul?Km&17k#NVu=w~tVH z;30nOx7K0?eTG;bBV!KA`M!wEo4kOmBjkp#134>q(VEB5F?coR&YcV$8geZtfUqYL z8*+`&3m8-t=W}*k488`&Q^ykb@QQ+LHskmBrvcYNxKn}laAUMSOp|&&=ji`E=Ur%B zIky{o&RZ4^e&Wm^2Q@UdIM@;s5(WeUH77e<=QzDz8TTRSjFt($s=M_K5TR+*qM9aP z-zD2|sZ$32W6j$+bDRW#-hUP+jmsdVrBVlK^S53hl_;iFvF`|nGBRodLH+L&Xdl1{ zv{G78BueW4u4R+WycZ!?m+xo%UCWke{J+$)WBxC-Y?aWxvdsU_1vGT=e_24|j)5`r zKVgQl#y3D;+adI`x;Y#*EBUZln{MqP%2OS@gDGU8iWX;9`dxQ6LY>T~?f4xV3Th~P z^o^#%>x43(F4x8QKP;eOj-R5u0gnzi+OXbJ`$?JUtLqEL%ymCFS!*&9_%h;XJ1Se` z*ru2jqqI?CTT+cEEQmTv+U=Jc>fpuustv&opGoQ-hft}40l%Kg#(K53yiC9PQBcZ# z99dE)*_r#2DJy*%>CQ`eY9K)N$kM99D70v%0=ry&pzVpv(U_9V{Js%E0zX0Dvy)B1 zmAH5ObW`3xwGlF)qV>xYRn2vCA|p=nX!$*P#dN8^(xHLoKy_yK z$HCIK(H|OumRw{iwd9ZAN*&mUJ1^~T||XZ$8a;d-lb|Qu9-Dy{IG#FALCbHDe4O)C@(KI-+uTJjdl_$+p^e$+bK*T!}to zk7O>>h0>(V6}4>^(5K~Pmg}mM$^}2XCXVH?xsDGtwTCHv<@JFliLKLSU8-0OK{H~QLU`90ZoJtfEwgY$>$CP@I+{xF#T8^jMd(Wm6Mj_vjP z!7RkU?-v}0@V=*>VQEQr!ftDYvgtylIQ!D-Vz|zv1e|j-PEOn`?Q=V3^E~PJ(TE|T zW*#uHA#;1+W9N9dvI@4$XU@3dSD)OuO@_aX$CcEUPou3jJ4%A);ikfiAHwL(I#`?K z^Z6q|$eR#Bu}AaXKt6PTT7wyOf;rVP)E4P2`M`qyKqH z8+Xw#4r#Q0W)~tqTg;*_+f&H<+dU{u#42bg{Qso8G2a(>1ohdU7zIV@k)k zmJs`aQDdLLeT;OxThqbNa(t0#Xb{~4OUA_g0keSzZI5++Jj6xF5r8uElALTgbSJ>U z*eZU)DE;&ai_fi!fE)aLaA-+V)_lrq4b#)<%HgYZdVE?2)Dyl{SvV{r)UMol=5sxE z7ntZ++<}lF%D7zQi<7Hkm3ge5!JlyK^YyH`56r5PqV-yg6c8eNVGZK_%%WLAU zxxg$F!69kYVsTy`7wqmvK@E=>%^{$rA4*{z`m>*WhDtl2dzm81PSkop1<^f&=6lAj zqO`xlhJe3ZWJGq5VZSDDW1Mm!->UqzA>+Dn#LhqTch2E)= zK1H?})vhzPCs4Y`3Lfrqx+63rrPs+Ffs6@PqB<(yxu23dHhz$HvZW1oj`Z&(^>C!q zUU~U*^X@DQ;D^R=^%(6EC8CZ+TEqR88!QFU+qD-LEC@IrQr*M!BKraoaC4Oj<2`7j zrctxA3e8*p*qy1cl?4M@k5jY(-af$cc1XfkRuU@SR#&ljCuhs=`io}eRm15m{bX!n z1HQ850Fr;Cv%5xnW~194ouHBC1tcG-Y*JTppUHDTDx|1i?tXV$m+aO5E6Ne@6`tJXGl)6pjtq|$|ZN7fr{ZPav$n%4~DRv7chQCIUai`Uqb1!Q|kx1`Z})a?MMEi#Mm#n2xJuX9eh_joXMtC>NJS)5<_xBT ziivv7jOfN(j;WgS_wfF>5 zb?r_I$k~@DVXTL(`aJ8A7ckBLRXLwZjel|dT&Mz~K{7XpdHqxNa57>hEdJaypHOMu zPinJcU5U!Pk3SFf_y?V)(4=(!5DdrI!!LjX7y<_Y{QkV&jed_&8p~{APXZdWjyZSP z_5R`YzL;B4ZDEAGp@hn`T3v#g;mDU0rD(Do*c9%0HAO=SXH0+;rlJLH8ksw%8Y)^e z8B0nBIBj_NU;?#ZG?|Kk;fSO`G+A?@97~E9x!R4mp+q#^o&>ym zDv{KlL^K6kEQK7Iqq%e$@qDTx26J&G>0+vb)Jp?Zu~x)Jon^I%qRy6sN;6qvc*ujL z(5oTB1xtgfXU1#q;Sylg((I?Z*;iK2ZPI-PgbSu1z-mQ6 z$U|~JVAWP4hc)=&w2q~CoYW&KwXT7SxfBARY$0EkJD^pST9WJ!jcMM5)#fJH(|%0?(6sk&eQ#HIS&2w4LKemYm!l?0_3bH|chXArXo z_5Jys7_z5S3T`2TXNbI^i%N^>xGZJaDdiRJc2USV64J_ov1MGU#2ux8!Ac|mKnjL{ z$|9~TZxNSDwjvmZwcRH*JOOEd!W(s!KNx<^P$Ln3#3ccTKqw_%FyuNg!}0XF57(Tq z%-=|0nx9eT9fm&^Dgg#bt< zKX?nR)<{R2vE+A33BM-lF(H^G2LYzb1E3m!mu}idBFBRNRSU#=Wm6kmBNwy^ssTa-23)V;@I2ahlA%VTA)_wR76cqmEvn4u&e_1r-^_K z#oBXvtn>nY11u4B;qf$!Y1F)YU3gJ~)d#-58EQNjouwR=g0rGMB zZQm1N8&ua>MAEo_i!!In$zYhzKyh?T zmWnV5+!1sH7gSoK8bRic;>sUnl(rwFWJav38$VSa#~<4SANrF3{CKJLoRsuo_x}|p zmlpgtOqK+F{R5L}nR*=||G;Dvq<_NX-x+)&L<+AwF((E0`cx&u)sR8PJJ^2xVC_j? zs;J`Oz7p^ij0=|xH=a1xZJzsUBXN8V%aR`o{sg-Ba|=Q-Z^POdK_oKep|W#Dw5 z{LC|4QkW}N4EP0t29JUm!l>%6*iox?Ak^fhP9haAeTZCWnIw9LBNoN)qRp2_2rfDW z(%y5oDH1c5LB6#HzSYCVw|vvD65GV`4_rJ!0~oY}`3o1bW5q|*e%Hn$9YYlCPbf3K zbN#Bf^XrTHkdbZ*U?hR08_+Ikq>rzWWU|x5KoLeWX;dUK@_kvJ9P$%n3twIklLd{{ zqjFRDiP8i_B>);b&Vb&dwPQnfV(u1f=UK26=e3~PvuHKeQfvyRsX2vpnhc^*CbxMw zyS1w^ft7s{2N(RS4;MD=9}yg_^RZx-T}enZ2JD z3++M{n7=X=7+3a&peEH@Wp0Uv3<{FF6yi6eu&|P|EOQCb2@J)uT4ghCqGFePT4Sv_ zCMz@c4I6p>F;1soXF9BOPSxD&>!TSdV!3KAmN%JtxZEWg0YXGEnD)pb=i_XtMhwoQ zko_Y3e4R%Dcb#RPm#jc8!mV&=o!~{;j6X~|JGU<(n+OMAbBs&_#j5uM@ygMpbucAxA+ri|!pdJocoV{Xo;>p1i@;n*Bi{q1t%1oyH=0>>WG}xMX!&Gbti# zs=_b9y*27md5i=_ntLA8w^SvK z<%^k(CxZz_KdwcXI{)(%Q8912CiyyQm^$l4)1g`Qwi=zFlO_Iy|K#l1A_gQ(;*qF` z)r!7ulKNXyDiyBYGic%L^dn;KuQmAoZCrmQ`%yUFpm!wMce}u12K#h*Lj#p*G5>>p z0J5s0EeYYGn12R09PJveW#&VReL63k7P*%oyES|aSV4xrXYO>0;<;TXY#Sqx!>|A+ zygYVy_@?^@5f5)yc&}-jo8AHvMguh98^}zA{TtwRk0Djdv%YSV9ms|*F7S<3 zAb5ILP!ORPZ?thT;z;ZdmiDIYn=MoKp!`}uJ>nb#rM-Fc>PM1Z`fr*n-O8pwvq06I zd1_AmF@E4!9kfKG^9|~I=L5#%l{f;IAJk9mEFq1F(!R+Lwpte8RTa#0jyzoB#QSWL3eZz(oa7b&T``w?(HqUu9qqWS$4(6ulBM>>?M+R>KZf7nmPoTe ze=ZB)5ws3DN!o6{oV?U>O?xOAT6vf_m47U1G7s#1d5+RSo zBKReD9!7;^UU~ZSX+b4%P&rgdzMN&iOi8eiz%*#C4T#il`Q+wfG>r-wMr&8%00)mPz8`lfG7+4bT~j1@DZ;h z5i<@!$aFo2Y0Fhk2hLGX_C4_6WE@YZf};g2Lum7BuBBTHYkaQzO`^wtg?)2VV!&eX zg>Wv6Wm22uTeMmZox#G8M~1Ls5jsH9oU$lS8H+h7qAnsg3H-;tP#Nge3V5T!!UP)u zYRm-)t@GNDZuEP)9HMoGsmTljfOVtHG?9PSY--Fx5Ftxhz*C2g;$NQ1tUK6uwOhw7 zJP}KT|ANO&d2G_Y`%87g@O8J!{!pQ}#xrq@HWnODaA-p6#9}d)LNOy=61X_54=sxO zr4*uYLdkwQG1dKE&*-W@tn!crS;RIWym8=ZzXgMpp~#8up*z4#j&55vm|-RJFXh^F z2a;I|^fdJ&ugz8(Yy5?czsT2W{e_JIf3WeGbGd+2P=wDHEN`>5k0{ZKcfN?x$^jDm zy7&=GD`x{656cR=p+O@CoX$+?TZM9A9!0n-v}>5URMnIx zl)wj3Y&8HudcVB#(wcQBB7V&qSw&KASw?zUTDs1}HG2Ncs)9%ptyxKfg*#nK}kBTV#(gM#IYL~*Oi?RY}ZI(t!D*eCI zU>g0u)nHPdg~flW!35<6DzR1Ap`*(JY+I*-qR)YF7uEKT;HwU+jYpp*3H`1Ag0D({ zGlf^w*}$ke27mdHLwu+1t*^-K-N%eFCy^w1cZE!J263eKk!g?hcbw%@R*wcCz z&4mZ`bb}BlsnD6C1kYfe zdLh;jCaLbY^blX@3z}rUGNggyB;H=j&MU8sd#y>Ivh()5wbk=C%`twCv;WbDErx95FC!F-^1p`1)`I^+ANmVoy#Oc?cla>NAe3w8yDg( zJqYa{9*98$HFvG%mB`uAqrX+)XTy4+3XCDiJkP>fHQdXc>O4jcJD5pW z&5js%l&ZVCx01xje+(^4xf8Vtw})ijn=~e)|CC^31{UY&HllaufNfCe!bC}2D{1!a zC%{P1(LZ2<_udjWIb*)~T+A$c3j1C{BD#)>7*gfS?kS1V-qib^p`)9;v(fmWQp*|v z?q#6Pha17C_Sf7sUe0R9JhtCf2%&Z$kx27n(&*oqY9pseCH!V2DUYUezS5wi4CA_C zID7oiwEu0vo+{k0Qg}i#05`k5xo1k104RQeS>Z6ySxB>60e#EVKSR^*lUE80LiLPV z?iCXUNlqXvuC)Gbw#VUq<_$ZbgFpfmas=-~?wmv8x{!|PgXp9!eW+VVUbR2ZCDV$s z7AD?D&79MNsa;xZi5nxgcJ{NpRvb2^NL*3)p3~5{CgfVq>%FshB87OhR`!gTL!~r`20_w z6Lm>x0=&+*S$ECI%)zuRP=a8nQe)y-M1+uUz-XCyLj8#>6S9`6;AGTEk3RUcQMe(kPCIyR4kqFMsKi<-l591$A_P6gq|?^ z-u+!emLUxo+ zz_m5P8- z*92Q%kR*kBB3rlQFrRCc-aN&<3;rRUf847IIpPWRg*IAp^t25doz-oh(ki36>Hx*C zGg=l;(kjn4_;JJn>y+=el)bUiHXYpnPx6=@M)4NI2DnZ-%~|5{tkxfkp{iByj5;$8 z!c!q{HOFnKKXaHb&6ecHFwzJ)+eL8f9`Ic=;Bq2mE|@rC4pBgce=Rx^MyU@;7pdf zg)pVrLCX!!&~kuXITg$Hc!CxDww7M(97o_J=}mjxnl%BzFE*$=hqVd?;B?vWuQ6(T zCKkrVc!**?p_njtgqYZ8us0GT^=Re#AV67pueaxb*F(2OAiIjIiBeJ<`fCe!8#*@c z5HVjDKPd0q7-zM%GHG77(aBnqp3+zD^(wsPZvga!^@`bCtM5OnB*DFbL&#-~tJ^4C zuHJVR-~${i0&fX*x8Y+!ygfZe)v@Ijs3!%d3+P}!#ZAC-P)+7c7vTh}VC5mbO|%8x zN}WO5xbD;L>-}?#+Xt+Jb6&*4rvf2|H_E)AUT;_}R8v%Bpu^ z{b-1{--C&ClefJASQr#9+Z;i)G$gGulQ$wnM;MZmpUM5f zabhW}F>ys`5u$Sf?xHber#iGvIM3YSTY`Zg;?CzP(&t%t|4Cyi_x{rwRCHsuz!~<9 z^@2ypO~77~#+1Cc!w-*;*~{f`B7se2)0hYv3%RyD2ZG=-fn%lN+_t^)^!G41?8ABI z9*mub!|l-U!5ZDq_N5>VKNAn*J_@$UqtAeUbxRe!JbNBQJ54AtyaqJxf7~ptXH#&R zF^dBIqL5_$=^94T#hSXHyOC~5dr>@nsk!?-l9OoNahq)$B_WxspuEG85?%jakc#33 z6QA-#Gs^9@N`@o-#F~(?c~%pRHu3B1&NuX-+DXqxLDi8NI0V-Zy5P?`lAaGc6cgV-6>{S`cI<>M;Yk}TfY=$Pplr9eZ zBRrL2Z55}O@5WM{;SW~V|AW;z3?MW=iz18ZjP|O)nm(c~ER|^?mrPLPCuS6H!-a21 zfeNiVBloNsVFtBDemqjsJ<~L%%I&HnlxbYIi(jA2@ai|_q0XkgHQdnBT%P6=^i^x& z?Rinmmd=aKbr2&@nDxzvKt2g%b$JIElFe0&X`Y>~n&tfBuyU1s40}_NZ)f$zrFX(M z(JtPPCKz{4?MS^Im|3kwPwgOk%D1j9`gG|8xRYe6ZzL8PJHp`*Rt5O*iYlgflL9N9 zkpBSf&Rm*&5|RCmCgd2l%a&H1fQdX9Y`#kg^r<|AQYM?k$Tbg98v{`jg9L;dYmc*F z$mRo9ZKkqzdYDeD`r7wl0ws@Od8Vl=T> zQSppTB{BF;3-i=?K{Kj@50&RGhs|EP2GBCIO75M2iVBz9>h!k3_dL#3#Q}V3L+A~! z3V7@TBadz((0x+c5*jZIBI#WtcjknhwN_voj;xcdkufLx{}tcp`8FOHAw{-R#C*CCTDLZnaELOawyHsYqGv+k+miq>1 zl_nLGE|igOzrK1Y4cHzVA^K{rH<&j20P7)^`vpH^sPM%jdvPr3Zy=CYAo&*{Pe$yN z8JnYElCQMCddI0Q@X%cynhD=8Te>G0;&;7e3zj#1+0+)2FEV!b;S7|e37TUT=98tC z+p)&PE>=}++BdZ;S-|-JL)kkANBVdDy0J0wL=)Sb*tTukHYT={i8-pvVU;SCvTB{6gv>GYV6q;yn#N_mI6aM>)x3n75 zs-rAG`6Se35(|YC5RM_K`Z@4Q1v_GR&622hY6kZW09K-({7dM%IR!b&4^nYdc+yBk%V=*hdB4=9pVu;P>dp31L3GOcCD>P)f+u?-egh`YIo{;Z{7&?xf z)pA5(xx^JiO4xNazbuu6;ztvt-jgLCMSnb~RZ`PGz96Jg#mt-VEA|zFKPx_m&7mVK zj;brLji@0Uil5jGIZ(_!rs6gaJD*kZGOCEr(oeq&DYb)Z2&J zYHtvKyC>7=gzoa4Imf>Y-kNo+^>~h@#<~UpEa+GVX%&wr4L$;Y)VTAM(o%MzSCcvq zElQB8aB&u^BZ7#^2lR3aUl9LoLs6iD&p3AVb!P)w?1l{ZmYm@%HeP60cY~QV zViX_1(qfe}w=yBUrxc)uy;>YrF`>|pZ3R=c;!xR9^da@J&YL){BMRzxs@+R;-f=d zfteVubK)9SO}m;Un{oSRIvUT#&wO|4XCP^J2xv$` zBqgu6pc&+37J0mX5bi??IVH$_z9UJAK@5=0g=fqCh|i`kz2x?K)dK!~CuvwA%5xUq zbkwf-XyrRXn;TOq$wEuN>TZsGn6f*KE(5d)pwyFF2WPsUfKi7NI9W~)j%9xu4HJ}YT5NX#w<_+lXkIQnn!cOMVW4GgB3(x9t+HyK^FsZxT2X%opl zX6Npa=lyH)tO4~zMW33u6qeE2VlNhq)uAT1BCWuGe{a25!!|4VAC_mAn>&L7viv5H z<$)tE>TA1cD^n1W3v5nO-qM%XLf>cDf$*C0FL*Tt!mBHy)^eUJ;yP4ZQ?=kZ4iH}3 z{|&Fp|G;Z|XnoR%?IN4SJe2KPUK8RQu?jt_0()!p?~!|Q1W4t$n}}e%v1*EW>)1|j z=bSEHtAI`{bi{XQiGKVY@xMwq>*la*&FUfELr+2zwj`ugk{{o`=|7httXX}v35**f z(y=uz%qR(u2Sw*lG@^?yqI9$B^7CbMFLSSz7g`|x{EHTvNs;RZ*^L!W9K!+ha2(5n z#IjNb;@(6w-AjjlPs3QJx`q8S?J86-crsoicoKDv0-XKWh51kP8;`-|yBCDezQoNh z$AkCuT-NvrR4c+VxM$ncP8bgpc*kiHzV-!Q>R@&yHKl5+qRzq-jD8lZkwAdRM3U_# z;yl4?Q)N2js%JT4aQ|yP9#haIJV`i7&EXD>41#F{9%nToC;2_us_n|kzSL_`4nNg} z8n8|DL`tSYKAJ0>Azr^d5e_zs#J-@D5fgO;gZB4r78~$f+^IzP6sL(+ETdp7#l5i_ z?Nh7`Wcnw94#g6~#tNIvP3W_6>A{N${Uc5^Dp+mh_{9HO)wU?a;kDmMTxmsG9!OpvNh|+ z94Y>aB>;#-9xIA9Ic8@0oxe6kyrx7*Hg~q1PNHLWCasH27P0pcKGZLc8(aLp!bHC2 zgee}9zRf@$RML<{Qy8O{uIYmSeiaV~qZrVU;PRSLRjz1+6Vu0DZ>Yyj-oEpVz-N_| zpLn#YtX>Ojw>ral4m-1u#_%qU#&@}|qBlwAFI8xQVkYg`t(!r3V~=Bsc_u4@#vasP zYU%ogoCj{SnneCMxSBL84m}Ufk&g5ymF*nyJ!~EnFNW{}5xDNzAURZYNHp4}o%qh} z_^1TKu0+YdduCS>8Y-eqpz=^5h|@HEf}03QRFC3dMXsLB{&B6#@HnyFIa8>D3~A^e z`FMQn1eiew?<#x%DYgOdB=*_=clW>Jt6~ek4`}=IENJ&Ik@u`_N2SkxGbsd1*S*&< zFLAhFEbTYigdJ5kAil2r&-kil2gKKSAif$}{r|$(qkgrCuz%reRMbv)wlW;dVXuw= zvp7gnsb^m`h!v@NX+P~2ZdF+jaj!X zxhr0-f#0Sk;kso8{7CEaE<%1RIMeAbl(y8C0ZUzT(8>GkW&9bq!;63A&`$78vj61J zQ4kin0$6f&F`Qz0+#0a|6+_cZ0O>W*lyv?ULBJ?bcPv${7)Jj;^kcP3-r94bW3W23 zv(|VbgOBG-0p`Yzs_J};S>{iF{Fb=&;VNS`*TckD`X#6f0j#jop`C&j=hz4~D2n8X zn-3Bfcf0{Z5T7A#5QqRFyk0n65mTbebUsS){|>7Go8QSO#XEWLZM6-sZ=8_7ua=nt zwTeXI|5K}g2Wl0iI$gI@lZZPH+cS0NCyM`R8wc(2kMjo)Jbn{8|mdHsLd z#`bPO{}nXXSWxyGLi{Ue&SsTTp-B8Mts=GU@E@(>5STPin+*RuX@;Jh!#Rj>_!+AC zl}9U^v={NXIH63i{sB%Un5~H+QUSR&ZU(HOG76cD)2_8kR9+|&+0RA^iV$oPu0cel5BR+7Kwun0cv=b?||Df-nWh4*$ z7izBKAM~FEQU4CDE3hrAQh}j0RkB$&7zK^{@gkXRVj6&QU8B!4ZRq<0e6)FV1uEUL zYjnh%V7_sZZ|Tf(k+;?9{yvwN@^oHuQ}+UI5CKtLQQc~Z{Pt5tdf8l~DjRD)m9^kK zHJt_xojUHR8i}+jMum!Y=~5;XWE$QeE2UGXCMTlTj z-SAJyizWbMqsFZAxxJ>fxu%j3>!xfO*{CH6alB_W*j1{#i92TN^g*?kZ)%RpCZAfY zx6~7Q;}g271Wd^{!_o=aiNc{XpJ0W_`>-V1_hA|2 z)Uxnb!x?gM{yTwgGUdAl@{UEyr9K(|qPEfB*Wc4Kb-`rv8;uvYZCYEy6!XAVL>(5#-;4(=uo5sPNuZQ}mD{A&k3iy1u1!{|1(+x1$8Vz<45ydzY#J znZ;n1oLH0-qMo8y!z`PEVvo4Ld3bqn3}QTw{lb*avD1(xHpY@h4Zbzt&|>47Jgzs( zUfP{qZS}Xje!Qx7xXLsPcYQmR*}mz}wlS%+$plNgf9M^WY_J}spnQGI)=pZ)g*n@w z*7v=s1jB;&d|FE_ckw4QjVw>*_J{Y{W*u!ItJj3Dm%@X_OC6DqiY*kI&%%vj|8Tlc zzxd6-4vBfZ2htG^ztu?IBBl)Z)h9`%;V>!&FX<%+?@~dS^yt+c6ol1YcDf3UTw5XyU=J2qmoRb>WAH`-{ zbYk)d@UZ!L%vTY6oZ_lV<|x*rLeAvcc18*( zzc{`0FGXXKzh1uH;=;RPioQ?<87+xda9O*FT;2ItJEmFUFbcGE;ap^Qw)K=+-D3du zN2YMu@Y$uN`*G^4*OFCAVy$MA6xnRMSBh|z`m7hmKMyJK8t1A~61karqU*mc2Bi#% zt27jkZ$TncoU~I(v4F_};e0zrm9}IlffhEfWQbg@tr@vVe+@s2dK<8X)x4DwCRC_o z@#RwVa^vFTIiLga_4apPa_w!7Zyc~Agxge@{o;g1Z z#$J*RiQ<^hW`UMRf#*^kt5a|a|tcewI2gKH(h=;7nQK)>j z7X|q`Ts+>#n4eI8I(SohT84Kw3*P2_b%!Ztp_GCxGAZglV}6=OY9hc>E!T zFI=xmZ?urVb(Z0V&9 zOmeJgTQ!mBlZBnk0;h^welMmL_AN&W%IyhXEDhRYGP)!CTc5}$Jld>i#K<$m3#oZY zH$?(b=eRd2S$R@=^DSKj4zFIZQbb>2+xw1{@u%#T@62YKsUKORP+>TXjZVJec-?>& z4&vZ`EK|smg-KbH7)jA04r0~p3=SgXW3VNw(K%ez+zfThp@>#-{@A{r3Jz5bvQ|Yt z>4Fxb>Wo$loKe+cX`bK7l}-7gM&xES_sd}4=hp{^O>wq-k~DJpAJC@kX=mlA#rk{f z%6tqO;dw2Z)Z!(rx_C9~!A3P1>p}E|xS^?GBi7PpwOGqT4eA87*s?p1Z{7qB)aIp2 z@uo0Mp)weap_M@z)<9cK?!jXl_%|iVA7xv3UU{nc<6}OKAJ(G3QuMs#@KVW2yc~@5Mu0*S5 z@;Nwz2Z=gFIYw-BrV^YAgYl_#(!ca&&Y?xty)pN%xcUsQFacR$387JR@qZSqh5o+< z>#)45D&0ffW-m`Bkt*u?i0>?wADfQFrPm@?*>1)XVWZKZ;q2koo_J0RaJ#4K`|P2` z-iw_&2j{hkY5jCAvpmNR^qe~cirR1#qNFmou8Q&HT;~qmqhGXycf1dxYWdCMyJxVL zjR0{)&za-KvBSpc(}AMy^yc6KdQ26k%tY-6W|J69*irfAAL4RVs>HJXEpvlHEHVzQ zA)|89!zar}Zv3+o=yLs$P0S=qQdy368s&qJ-4t!jP5mvfR9>;0`We2!QXn}pt2rF)r9w`}qVE=v4!>vhzbuRPdYzPR9c8&5*2GvZ-Z2vAqx z2KB{{NF(-7tgpE-xMX*)Z?;WToQS?mi#(5;79Np_8BEH`37EiJ1a4C95Zj7VSs;Bv zbA^bF1X1~6g#Dww*i)Ieqt@aCDuni1($GHE3}#{~-rvO<&zSvHEgopA+s&c!&7yv9 zQ|Pl*uV+lMM?G6z9G9-oga&;L*sfqb;z(QSB9u72Z_W0CltzbPTHne&EE~oJ!SlH) z8L~n%vE)LEt;-rk8mY>XBP1)il~@#TjOa8$CW^3g1W!z@EjgKf*}!#UhiJC1@L)ZS zw?+5Y<%q~C%Yz#iH7+Z_*9Pgv&MHSxHQg|Kot+4(%U1dPtg4B=)LhMY(C%ia3nn)u z&ex1tROMDsm(|_xb}GT~Jsi*fPdO*pZvV*av~o*`bAP1C9pTJW zenJQPJ>M8S6s%t(B8xK!v{(vOK>Vkv1E%&DsHijzoF=qM9wK;Pp(mvAw}JFe2*vtB{He1bhu#ul?-W=kv!*OA-m6=j#LYpormo z+i^Tl4dAaH?DSEMk{kPUX;@&kZOOtV!pb^`1n`MCxU}DBDA_9JmyX7cJ!ZaMkSx{ z$w`&ls?rSg?j1(XVK~WsI|M3`mf=+C)2%Td$w4}_kWeK< z6)TxC+!2nk)b3v>Y3UjdbJh%|xV{c$7=u4ojQGzK+&{xo$>f6aKiT86a}P&%BfbHb zdF2^>UL%IRJ_7Q%@y;Frd_hKl+~_w{2nk=QFCOQFRr8AQy+aGl|T!N$lT!j+*65D zr$3nVN8a)4EdL}0KzDV1T)QGSe)PmSh~EK>L;0`tzpUH*kDUP32fmbA=zCjDf3M1! z`N!kE3)rVME{5~lKIGG{8$iAmDZnu9{Aci8obUWuzgxWeGZ3LWCJ!o?I}}w=@d>p^ z%mJdiz&Q1Z_)wVu%<+O$mI=fdc|Nv|ahy)5#Xi|fV$8v?vM16%g>T?pX8ib2qqi5P zumdn9+|8K9*U3%8y@cYtX3_3++??4-ZizNeGlb*367?V6CS%GSXK(v)KEIepNxC@L z^z-!Cxzju|XvM@8G5Q>**;v`6_@f341$Tv1B&+Bt^b$dDbWFsmFzKt9*Moe%5{WY{ zzdXeC5agN69vA#WWUM{N@JWA=u#C4kj`!ngzrDMGe+~G&WQZ6%WnYnpTjo} zGt2Ki?=YFe0PL?;^MmV%dbYP7bSBUd&M!=K;}h!wJane@e!>H{x6r*e?#S;OZ$rA&hbiB?jh3+Z(U7orGEUMTEbRWlx3z zzc9@A3)Zc%bKIXOh10q@9yC6 zflz!GNc?3nJ&NyzsbQ_x%{BPm;-$XZ(p^L^afTnw-~u*Y)QBapO#`n|FX{(WaswXW zx&|yCcvYWwY0_0Yaqt5r#OIuQLw+Zt?gZb{{ubDOq?QR-3}fpj!LXA-;P>#TqzWpip=%n?{rN-aIagzpV}iWn8m6zJ63q>q~Ri8 z(UTLMurqPZ48996&CD9O&28wbXju`9Ves7lnbYX0jCCT5<-#h3M*K((t7?md!|@s- z5+^vE!Ej6MqkNZZw`|M0LsD9_eymoMxE7HnMDp}2pe6Hi{(~f|Jd9dXG5xKXv$7VD zX+(S_vakiEb_#g!SJVT{<0CzMUGw$zUjh7*D<4E!0vE(`XJuAeL!_l70T&`+XQ!99 zVqX3Ce|kug!lcz*K8P`ETS{&g>*r63_y!5|$TJ5zZl<)to-Q}I3a}D8;F}J6!nAWZ z?5wW9@}$1pJ6`X%{jL?(0h`j4X@E9kitd14UQMv;iH3YkUV(H2ayFC?-rQAcG!14F z%${W^O|r->HCnd?ptkOy4S$9*5OVKe0~c<7a+1-XzIZsEo!hn}DVEXzW--hi1|fm3 zz>o`gY67Hr!ws&1GwmtuG=sn5aBFx_tqN#>#BGD58TOfD`%WY4Nf%*S#r8{q9+T#c~CqPiw+PXd2@E@ zLe|q0;I^gKA4=P8%aMS!vlopLeG4sNoMv7~0pvG-(tr5Jhy?>rW&DT7FMwX(*i$Zw zun1|@i^pd%{OjI$QxqJzLoze@`;T#l{owsIO1^ry=0=ZDS(0q;Qs)r{etw8?xk5;D zhJ7#*#Q};j4^iB?WJwluSfRdVT!oTIqlM!WG+`DW40Kat`3#T7Lm9jV{M6>bTS~m}zD1_Yx`s#4^F|r>m!brPr;eXHR z26!4&E<|aJ+g~2Gk-Iu-kPvUTvGVo#;I}KPVWBE+wgs;pPQSwV0ByOo%wI_qhy+fQ zj7lhK0=+gy7~fb03T!vam?Z@SI#=YjSyDCZ6nNfh&JpumTvhXS`}_<@Brr z`)xpDh>Q%K5YY*)#rT`xwzm2F+Y}Jd*q$rLcyU1@G-nslspb0k(H`6yE*Y(tz(eik#ReS2(nkk5=W|GDP$^c5<+oVVq99`Vaq6ghSRt z;I@f!;od`f2Nn;;N*530GPC|1LW}iQw2_5pvbIK~0h9{g3rOZQ`W@dJC6_pPj%JcA zINl>uMY3;s7P_rC_FQn;r&Sxee|C2*KQ#B4n$yUJ}7q4C22Z) zTN-(-UfFLB@~BFeYO$sA;<9OxiK?u&N;hqm8KwLVq1|6$4)oaWt)>6cp1jXQz<845`yBR$J$$hT|Jp`9zcnRrn554%yJz6orh5AE?19(98|iJ;W*mL?H*Uk3 z&J(BNny@+|u5N4sHOz4Qs_#s_EVi)LU>@ZgbVpTfIHpG$VYeC_plv~G5?P&di{Qt@t4_xTX{ zN6zSF{MtDHFR5b27T7aOh;a_6v*$$q~zV8fBxnSDF4NhL!AX9jxN$+0OfxGN`M zt6P~{t;kceO+R0QQ6GldFafdNo7Lcqf#kzjC$iIENS(huUXUM3ma~U9i3t4Vpfp$N zh!W9#7kJM;$rPV|gL0GmP@EC?X9EH^WzI+RnYYQ2$kA{UIQ0XzJg+h(@!g5FAl};K zgH#XfW2-%eo4}z0t3mGj)_1ROz`V%&>8C~Xo0JGdl;-d2(PQcOi(u-&k4x`6qK}>(f-=IJ3un^jPXBx^Wp*MegccB?2Y=a{C6K>^o zDKrf(AP3xd*NvAW2S!J87RK>Wlj^X(%!M-PbK3F49EQt~T!~uckZ7)1&Lptc;j=6T zcnh;C+p6zQz-*gGagr!4kLwuTl(TXGx%oIX3AK$~`GtyB{Kxgl8TI)LjQQsDGOb6B z&)4sHJ`4c41=9aAPGjn`{xV)61lQc)ZAWgxzFEs1Foie zpmjccW6ig9nE|n~Z<`OR&#wgAT~VGl+XUPA?l0L>$J?hLd+%hwxx5*knQ5Uw+MSr9 zj`Y9BHhef_R^th$Avi;PZBM-_UPw)yH|o2K3|}?t1J_iH|43(sm{y*QZ2oB34Z54j zET;H=b_LM2$~KC7wIg))d#LgR=O$wut1N^+O1o%IrsWk%>m_($owlB~(no30B zy5z?Xc}&yfD}qz4LUOD|@MO011Z*h6d{5Jf_xHUxMO#axYW_?h>U~NXRGVeAin%Hu zq*i68DXv*Qt|WS0WSsQpXj{~Ng^^DB_Nr6?KELkXk$ru?+!+iHANe1D;5YGwRwn4b zHl+HOJ*PBW&n=C*r5s!C(h>3>2OlW9k=lvI zJu0?oXlmU@nOjjsPIqH0Fjl8Z=kO-Z14(r;@2sCh+qoGcDUVT7_XF0%My$%J^2Dal zG^Gn+HeUX>g!xZzx#1^>@BTkxLc?C)0iS`*z3C!E9~0es&2e`w+3eW@+d z6pEok)2*L-=}le78d3JsCz9yIlf`@-2?OsB+DdLPaw!!#j;MrcCe8&+XH}P1X;{L= zPeF=uspV9~7t2i&?5lXOop5hL%R5{y6O|iABDGdSACPBhKs~pZfBqyt#6H+?8(0kR zAu=BBE!EAmF%z2=>u@CFbq=hzO=d#mvf_+#r5Uu9$4M`84kuBaD*+A?Hhyl$z?drg zvj{oJI;g$)Hor1>XTZDppkvYxz3a?LUhh6g9eIBt^7Ab*pYw^M18V>0XiyUEVA4s4 zj=7XiZuywyaGSZE@v?WA&{6MhCwo;3%%@0Hu9FoxVrSRof|ggo?~Vm{EyLiUZ zo6AeUC7pr4%M59LWmkfmyMn*Sb@k=*7V2tXoDq5q**02cbyC7lp>7G-%94hvEuA(> zboWOSol0J>@uOKjX0&C6KGS<;xK_0!xB{A34Y6lP0ru+H;IKQHv@G7rxunr)_tTAF z#PNt2gHk{0d>rt8g{uoS>ION-rj^c41mogvxNF}uR~3{|xGt4sRa3#Hw?CxMi(KMY zoBZ(JBmPViv*sqmK7oC)R3AEMQ7L9UO1}N6fU%2Y_xi6g4Dz36r&wT1lzJT-}*w7ngm1)IFX18+N^;An=?<_G!?tVGA` zR__yA6|#71w!XDbPjEvewebe{6X|{!sKX%;l6g_wSY2|_1fuPs77b`Ui!`BT_`(T6 zx4j4J0KR&XtkxcPr^H>UXBcCl*4Ei&akp z@>mNh{RxuVcdW7SzQ~$vqM4*q;jT4ib1Q|>jkKBqW{a}a5yCM<*??&JcwVT-Ik5-F zv)o^=KEVgfg6Vo1z5p3ni{(mhYEi3`3KfUbkdvxIgS)5sFtG~xWQ#?zV^mpFeEQkO z)h|{F%@MoFg?LvrR;G2$&a+?q=Q^IW6Xh%W7XA1`@-R-hL=3#Y6?KkW|KNGjAhV3OP>S$NTlx8QXYo{({OC1UE^I-FN$kP!M?C)63SYe|p6yE?L`zi2awGsvMW zs8y0ns0~Ed%)7#S!^a}#TR}9X%;a~c?8*Nib9spsfbEp}`+N23OzY?1bf)`;{WaEft# z-vg63ZtQlMMK$~mpHFJ&8qCNW?4xDi>^YY~W1hrVn`mifPCKD&g)W6U}g>l&Td%c9p{(W@Z^vwO{b#5=(eFL+Q1R^fc~Ze-Ne=Z`?Jaqcw^h%PPy& zI)9tv(HrG()b9g|ny>TFaE*?gixgA*$oel$5yuXlOJ%d@N7w!Keu#r*E6G1sfvgr> zSY6<G{2(FJU@k z!Gcj-u@=9eWOa;dM@!fcE#aT@{(EEwIH_-h>k(M2U~vwl-5xUeGL*Bx`@Dk7=;q*v zuorhYQ_7sG0fbhcnie6h$u$Hsw?vqzR4y+|?7-d{+hEJr&TJqyYFjpyasR}H>^3k#r$z9Z|qha?ErYsqZ? zWi)6Uo}Tn0tivc0wYk(Nda_}Nmt}ZPkLkpWn^K0gc|?y&v>|p>i8`~Sk1pHg6Ffh> zX-X$F&s8X57(2Q;k}Rv`p>35~MMr8A^H-{0AMt0B{kr+7aFfqP>k#j-4-V(=EJJhf zuHSjD4GTvOqm{h(ic>X@x=Kw4ekvY|+0t>CM!$!OOJHwwwnn#1XiUS*YQ7e&@7qO7 zd>ylvQ&SE-a|+L!Qm`MdBFKMY+6=sidnVEDWwFhV4;>5(39gv9t7+{zd}r^So}t=3 ze5mS>b#f6Us2*tyX{(-WALPuXu=ZO)hChMC4V-id6V#PNwNEVwM{FhN7*k5|qRWO#igPYGao`E$i)A;t8 zV>a_r33|Cr9ox)k=Ja~xz+8!!qHSSiyf1J}Z+o*!TTfeYLk|~NR)XG9orvwy2xpiV z15uC>2bRsUoty_lljcS|)YlzQNS(3h7Z5Agz4aROlD4(;h1h9&=VkTB$u55<(z&qs z3*lo$hGCoRrxsYtDVe&7!tmTxDr%1>aO{iADa_D`cGA!%9LwTU;)mKe zO;@$TIBEig881m^8L9T?@}|kLe5p5B$Yq$~6I(AZ3JO(kl9tly!G8c_3Z;8cm!g!` z-%|4_9d(1$tk&&dSP=xybF3&gymL&^GHcMYbS6^yEq$y#%U-x+J=vaW+AU>@lA&lu zOf$uFSgQD0_0&{X5N$so{lN5C=2CyN+LG{mC1p`i3GC6@8b#=Rkv(g3xecxBbfVf4 z0w9@1a~Zv{c10!lP*HO^7ni$*3>x}JpJ{8dgx$Egve^HbH6l19WpTtN_koHg=v+e1 zQG6}(IlJ8GQV2Xo1Gan!>2784XYSG%G)AY?{8fLpP)4+i!8`x{1rm^|%oTn!8GQpB zElGEii$&lx8YNpFI=mBig-pCown4*O@)cL;imI?WN@%-9&rMVFYs5vx`%W%>@k^kt?t(LD2f zW+wQ?=~9URXNf-TkgEypykq1PkXELHx?O9xim+U*RqOOcyCpzVZW3#haz+iO*|8VI zm2&Ddc#mGOz>^!+eukTrG1Gi{2pnS2kpE97#cauu=dZNn?K5h2coscVLOdBh5)0j2 zqNKzTQxW=lvq5ytDisos5d3Y<{dmW1-p4~w_hvs+QdetjRT(qyro11>+YmJw{?wv{ zN6@ERYu|^Ez?D!YdtJExAZkD}S{O0Qzh_T~ur-2>9H?n^{5A`Z=;qfQ%~oP0Zitd!1Qmwr0rQxjz4;kp>#jL?z?_v zie2~o!sM}mn`|EaCZkIr>nJQ*+ksm&O69QfN>_B1MdP+~v9GJyY+cH7Wyj`gHPZujx6MQlk(*A(NPqfBF& zALQGlK$_~GTbMbf?2QPSGaF>5txKuYBl8MgbFjt(CJFrDghM_E5WInvA6`79CSWbD zw(E{RlhBinE7RuQUesP`rJ`C~g!iR+H%W$URCu7-COj|taXfXS=_#Vrf@m#RuH zutd{03YB*p;RYFkVg;GO1mT06#OZO~Zl58HZ4l28L`_QwYJM%EH)#4=Z5>6TWD%Cf zAp17^+)9|%PaWI8FKvU8DM+)j8o?D&5-EJ`<|9A-*90Mv#tW$vCpdW4f^iMh;Ak{v z&Np@RTjQ79#rbsdU2bhmr*#|&#chd3F8^R4SpA$6o2yL1r$X^zRmv;%*hxV&0LOv- zAj&3Xe?|2?(?omudhCAX7$c2y>K|{L;$9+^)th=7JM|h6`l-kO_ie&$Ald&+fu`2mm$}3%c<;{MNG$-~TaT0B zXgHjSWHK2o+t^uWb9svuF#Hbwj2sgdqH}do#QLd#fvNr%1uv0Hid)Vr%lwEDCoVKTC+9#<2 zxSywP)r9NLf6j7-g(lOh={X=_YC2pxg2|g5a5gb-;Lor;s;Hb&qesnerW@YOYck!} zb5B|PG~Xl$UGaBps9g~$SJ6=9dB=X!?kaE{;d-qc`dS+1+|G^JGPAo-JH7ReY}2z- z+b*QCo@e2jy+#Oy%@QNgtvi>G^=3D?=R%hG?9i;+O+T z)_GK-o($gUEBhGeZn+$-Os4N@_f>#dJ(>kk${!(g_EH^ByO6~gg^&=QBt!MB{e)(O zd?o}90py7R5Qy=z@15ADJ4Z+U+Z!L(>)JO;cOJ~Hf#HDdy|zBQ80o4LV{ZD)R}-nz z*8y|QiuVmGqVNN4y$oC9qp(U!X=f=A1bpcFbEbGa^vdUWlkc<--rXAqrKu-lru%@n zF852jb+xCV=W`!86?6ANDO2q`I&MAJFB;k3n_2TEe2#Y)kCoMY8{c3hOC^IK1-RGb z-c|wdAPhUI3yTF1-4Z4dtq6?i+Y<(iAo@s2TmbkF_g|aL- zgcVX3{BOH?WB%8LOb0JWbw3PXEZK(6hCe?)QONq^Z$T7sM>RS74mi4fU*liGjK9aC zaHDg{Q_sjDy*t_A4G_7lCfKo-`0~s^Pbej8)0=E4?VHsp{OG_Ax#}k{@gTF$pAf!V zuF2M8-aku82JQB{^!dEpc<+L*u11}AMc;fo*kL+Rsk%ZsiH5lhn992@b`M)6+8=n& z8!oJP`7M(!7piZE0=H!pm}0+==Xkb&4_BG+v6YCQs2*ea_b{Ys*Gy>_w08y{wZw=- zYcGvE&sce)4sjDo#gs*4f%fgBQc?LfPmf_FBfb6&l+KnjiTfmakNNP zlB`$R8F56S9c2G`j~YPOf3QetVZ=Lw{RocbDJMLmuIMgm5C6T~ivku4UThXo7wg;U zK#YGJ&KinE6|}l&Jw`$&Z5DZqA96S{(vKf|!n!P&V->gQV+lll#H}P7=e#^3*2I=I zSeiv$rO&#i1RC@>jxjcEmPn!Vh)??l&cd77#ZAfKCn}zt_QiKfa*4BsPfB5mzc0j{ zf_=pOrZMYQAMeD1Ei<5!v_271EEx5BNgwj!0KwIesc(3(Y)zpOvHc`A;^5Pgb>b_> z7I?r7#tsM$#FT+t+-GC5a`}Jx_GelY{Ro*|RLhy5*Q`q7k9Vk*!-{cgId&Z^Gr29F zG|mHLN&`NbIPzea_s-M#8r&-`)!t6YP6!^MCpW;`2_+qxvl+Fe;zR47YaN{?9 z<70@;(gxSYtPl>W@tyePzTMQub-T`jaQYkJ{YDD_>nuM|}*MMEs*Cc@uhAwrYzQ`UMRVlD^A)rj7; zkAwV4JTqQVFbbLxeH{1Guwe^;{t96|1^R~O5f%_EP9h>Yo-xAFO#Um)b|Rc7T@o+& z$M3jEuyFpN95+AdO{KKowyjv%lt>O>t3~tRrbIz|f5_ZG#|)k`X&7-`;0s6v*OT0! zU{jS$CZ0Yaw3@)S<5b2<_9kw5q|3egnM$mZ#k#SKyWew+ncRO#nVb@=7?9v|OqR zI&Dc}Btsz`!kdt;2kcaI{fvg@Ovt_+B_d~J^j$6ZSifD-H!VUyoD z7Qp`Ny&oUo{WZ_u?hatH=SevYNXj)%`W!X^MAQQ)mtMX(L#@>R`sq2vc53Iwx+&{d zaCkGFeR1R(nrUAfY$M@clsp3^=)o4^zFf+n2^e2}e1$s(Zh9FN>SoRRCW_RW3$sGW zGWS^M#0do^Gf5DjL#sz0JhrmXQiv5&ms3NZ04Z5K`cqtKJ_OH@kH5& zY`H>mC#6uprJ?H!Ge5qHo1-S)4EZwliURHEFRR4Pck4z&9iIzps-Q*g8bS! z#VibQ8Ott7M(yWS*~sOO!p&&)b!m(sVHBf?a(*nX_O;))+8K(+0eWY+06l!TNkoJRFi4D}st`zhxGBjtA&%!gPjZ1v4_3)Rm`}ek z_R2ok`Pzw4xT_{n;~H#ErMeeWjB~oc9JeI{5xojLQU&g}zhA50r=SGk5~=U%1s4LP zEe)kFjR;%JpY{j6IwnM$abX`Jym)z8IiC>lc2&lHJq-xyf+Z38#3{A67wAtu5Ax5S zb5Zmixf&SVNwR;7CBJeix9cNP(jTzY)&cJT+QHMI4&1d#m6qkTPt^Y)DhK3`VFMg--2`bFV<>J9l2YvUoaqiS~xoy)vu*8mR2J`zi z+v_-OBi!5-BMk7e4|I9_r65#*Wvr!{=Zogo>5-eQBF%8o$)XD~aqcaC>p*>D?j;Xy z)fiKP49GMX8ci3Peq;HSxD@;~8->+{!iUPtXdZCP(XpK-8|DXH+cNktzfIi~d8 zMgnLSn=whX6J<Ad;#uFQHqsOi@F(o5yic_1L22v^K=HfP zuFSE!tJb`!$i&8QsqBk76Yky#53Rv-o`i>R)j#dvUY7^%8TAFmj^S{adTfohQqhVe z7l%`BL#`@SMv(J;qkM*ys%Q(Ra~G%|IIHa&8W|FeRNnp<00BY%zFn5~Zy<+5$k6|W zgu|c7{f)fOp^>~VEovnGV@rG|nijzDe-J=2ev(NayMsp9M-KQ?OxPmgy$1ppiK-nL z=pvSQd?-&gpelx{wR?&=k|}g$Gxyka!4QF%`@sDK`2cf(85o7GI} zlsJ&-VAC|Q5)8aM+qRsca@Jd7TrBKc!zo9sT=;`yP*zX02_VT#z@?^|?z2I^4_<;7 zmFQ8rhT4iBRm2#BVW%PF$Imum4Bw%6{{KnIJ)blKk&40wMjjhRt|@Y`&4rYWr7a0L zAR{5cZ-Kh^DcZdC(Ps`uB&1+MLdtqTOr$*MAVC0-p^%)>plX}G0c3i)r69?kAp2He z59Ywb;|Y(zMjl?jL(So3OjQQjJ4B~o1R2i)OrXZaaxLsCcpQ<*|UrOvx|Ng zyae+iOBIwr?M&S6ray_fS zwbC)hOuLHwy#HP0x59RlN zWaijh{%Gz8iB@~W7hub7{K&AYx%y*Aul~r)@)NMg9Uy8IG`s#IeRp?lMr}PWXEw$a z&1pF%MqIM|kIu%O(v&Oub&jQ`<#FNH_+G`t3gmK1nSQ|{DBR@;ikCU2w}dQpp<*;h z$Eq7n%2}HE_N$MC`s@*klJ1JuL!TmOPXrrh?J||TB}pMKQyq7~5C0b&L>74u{6U7j zl$c(8-=wg@;$jU;bfvLWW+kPorH$55ruW-u^=J#VrG`%l1&`!t{1@c*#3AF^5D>p< z0AO7J@KGrGm;vakF$W%kK9_L=J`05moIoyRKk_-INWCR&fB*-`#XeFY1ir2MmbrFU zR<5d*AMW8)SQSEY^hBK$jf9xRJkDVpy)s16TLLIviSi!w;TTc9a-pNARU!b#5c`bF zi+*i{?+`r#A4MBdd}E)ZG1WG~z#XKRgz_R>Jc-Bp`*g}|jOpO5(;|Mdat0)Sd zp;GX_>iiK9ViSFaUZ8G6)@$#)LD2aH`s~KX+@5sw4hpKT1-WlRKFtj1O3?2Sj_>z{)nhoSVm_3AjAan7;^6r zlVV@Kdg!7%`Sa)5{lC+bv*&%Y|F?;!V*jsXjt}i1Jd|^M7|rpaoMW>) zXm$r9Ub+1TdmXdO>md9jnB_+C%16N}+qP{u2bY^o#U0&LoCD4DEl1@FD4b1Yp$CT3 zRjd8Uwv4tT6A-5dk}hX2iO2FJ>`Z!OB%I_G7x7LHc!*PMGb@06a@9GG{yes!bBCF< zC$I;{=$orf6n&R8*#*zmVC__p-Bq(_xoE@>eBz)k;3T-++_+~4d(ZbF@+L_ejCl;i`dFUtVw-^*O0}&-CU&PmgfeDYd!4QybTibJBO`6ys9* zR;&;2+p}8zpR%$8L9_J#)4c!xHLw*-BFD{L!Ht0SNg10|7Z6wC>j7W{r~-f|9^0D zX7v9}JoD@SVvdagU<`mt1K{Q!1}(Ax1V0-SVE;@2G4G4m0HT~R0*nz*Gy)QidL%0# z7Q8!Z24u-IcEC!W)$0Gz(OZilu9EFZV_=s4e||p5$NxVcoErUq6VLqme>BI34Dmxb z$Ho{i#z3Vp@Gr$JH;Dfrc%?;lL4nVWk+6S8LIKbgu^0-K81uoH4@L8#oYx-7mMD?i zJ8D)`Qo0uw#)|ZRiWmv0U5x$z+f4ue$=P}TA|L;AX7vBfJag#(@f;g{-{|`#`u>NA zJ%Bz&Hym>Gi_&NQn+(M$)oZAS@>`jbe@M>m3cTGxpRUa~Ea8uP> zNRE(M!2~k&ApgDkt8`(B}9KT{fA?$5G&Q zLA-N1dy%+RsOc4}bv>u~HI6Q2<_)x4y^_?kp`{#8YHeTECo~I9ttX8^<+yK)^el|? z9741>hEK}>D)>ecw@4&co6Pbh3q2!L+bvY*T+Mb68vSQ0^dCD2jq(nSeZB%}m ziA$sTR1ETFH6I~SjoPyx;1w_t{pxr@7xp&7)bV?Ov%y@!5LCXK{gPG@pu5 z-a4O;nq#B-v|pgkwUUj$XZGq{Qter-zsD#&yRb%$($hYr$M||$r18x1^%!-hRB~;z zDBb$t-UiQ7@xOwV$-R$gY1nV_)W`o0P6ijJx%l7n^TCOU|J}qhGyXRq&Y_%R6ZUJu ze$%kuYvTMWxMB~ZeUlYof_!&A$TvYaIRo{vy_-9fc2DT7OQ2J78;u-tiy|phv+8fn zPnuRNsePDbRrG*-&k~F8s`CK_F1Fzf;+?O(T*V!#eq{2bW9RP!@vkZ@8MOyG2S?Ak zovcE=7851yi8h)U110U(+D%NpeS8vLTb?P0yUsl;xC8 z%+yV}q-b>I4VJh@i%$b|2^nH5c! z6v=sRs}x>J(7u7lBYugT-N5RRO*3Q`k6AqJTs-oHQRqI(@?lZqW&xQ6)Yb*`-(8 zo>R*zD^;~;$K-7^k>uPwQo|x8xf&mhLz*R5Y&m1B_Fl3bXNAIDT`iydRbNKEYQsTgjR9;I3A@Jkzy>6T|GX%`p7W=iuD77Lt-c#MQy zWh`1~LK!yIBrVRW1roOITx4}ph<0)C!ii0GS%@u_W2s&9ze^IVo;mkNd@Y{Prd_PWtl-C1&_#?L35GCVuS`za57Mc4DGe8A`uM{I{5D7+{9z9ioTu4q{gYuTIP3!t3L|PoF6OMuTNegC zi{(vt_|AogW1k~>2i;3>s(d3+y!b3uknfhnk;A*OMeY!_IQGziO&nz1Av(NF>WX*3 zqA+Fbi{-`8VDj5(-}zlw`zL4M8943deU^=@I_*1Im1nKzCF>Sz}^7`SIr;KmIt2cke0A9~&{uYnXQ-<`o>(1I#9Y;NiFv z2gP187h6t9WxdH!CYyvlSMHUhMCa>ogURpRiakxaLM+){$xu``qA4O<#rZ~gXu1v_ zg`som?#g&DuMDq?+l{Vl*u5#c_kg>I3?GK}E#eJjw&gZvWL2+`+lG-BWaL@0dl_Dw zUw$v%nvvmcXMJt2asUpqVau8Q!v9jX8Q_Ef=92r&kGZ@JUC>A$d3X>kQ|4AbIjwf9 zfBkAPmn5sKftu0KB2~}f+=P`bpEc1|Tz~b%^;~q-8Dwefg70c(S#IpKc#?}=va)&2 z2T~OStJ*X33B^6xsjI&_aq!`n()m{pp@pyRkj)7_=;vR~|NY&QT^XuQx(g&n>by8o zJ49^MQAO%$KTm75jQB5rC?%9VDGtM0RHn$~*vQ)`UcCCNbAEKx`6|?pgo%ssDgYcm z*|z@IyF;PtZk2vzG^!@f(89D|>YJE(FKCSh)@H;#tkE$_)r&j?w^z_M0pJ4smV0=JUTjxZ8By_Q3-PK()6H$XgxE2PEtv2lXr1XJ5&uXMxh zitts$n4l0Ne%HJSBlxlxtL0sAAQJ{x@M%8kqgOC=WTs!EGVCDF%22nMPbvkO;GT1@ zW$asl{0(^72w=m^s}3tw+v4>>9gU>%mkOmXQjkuBf>a&?GRFyltzv$&%iVM->>xj% z8h$qXyhHqaX876g^A7Rzx#8#i{aN{)g-wo7@j3_rv_TAAX2<2yA!Whb*g`oDVyf^Px1wLw45XT-09^xPqB(HU-XNK(JyA`7bix)m|wpr4jM4}#d7*Z*^utps1)^!;-Kul zesR)v{o=&v7yF`LoEZILmVR;C_l$xuw}MeJYQSh1%V`*;W4dR)4pfaj9F@i3By=G%P?UWD_1g17)FVXv4>$8r)>|zI5lAyd!t~O zFpOFH#kuif%&%V*2MrkgVmbYyY)JQPREqjVaZq+&zc_EZ2V<-A_Za=6vPTQ(7w5)* zF-yO=Fku+;>lejA14h4CPQNG{(mflMqJB{vl-<`aF4`W3abdzR_C>$A*pD!bimWHA zKeM{k0)9oKPnE$Yp=w5elT`Tthe*@OO;rkeH6xs^|_nfQn9`# zXJJ+*)@L4!*(!*M>@7WVP$k(LoIfz4eePzrRJ8BQ0fg1bcH>~LK4q|Tl6|Kf z?6bqZja;9**=?2U#=*YQAn?5s>-oXhHL>2#0NZxnFlfYjWsgj_?b^lqtk~PV66^WF z*fp`<&bY=Zu|7M<(TMfAo83~eelc0(f-CdXKFi<#HNlLNF@;{`1z`2}fA!CwpPuCJ z|9XCUZtnlu#MA8luiPA)3&6|;VDn!9_EXG6TYdvrj@iu>VEb_eSZ>Whq6QaYQV?!XDG&HB0P~m)N`( z^78f{b4lr~&*@Wd{|zpl_w)BZpPT!iH}o{K|HK>{qt6(9^Ba9PE@4}4?+NBMM&5oH zd19`0%P#7+5J(55%{!P$hL`L4)%Cj{DJArW&>18CLr8t_C0YI>=rYue!Tk_G7g2r* z%F9IxKyDyvhA^Y8yvh#ftP!j%n~di_=9$f+;-uACzWV3tVS_3wJ09y^4q`UN0hjXT z;{<_M*YAL;0AL1&A@v1s?VYlYO6%e6x2$(KG+7kvFH zfrR=K& zV$*ODpGq-!VerD>g~5x*H7^_~|EuQML;~z*BtXSpf4X0v{|T(4tc1fm;dwB;*I!XB_%A>VbebJ>U}ub-_UxfU7Go=;nj?MA6GI7;IK~DqVf$ z+GGpWsT%55p;9e2_5G@;@0+P_&D5Ktr1DvT{x8lbL%qihgIk3Q@&xLXK5Kh4fC{_d1_`C z9B+e&oW+esinW&!cXhj9QU5=)C&&q1M61Jol4n-_kBgJ%`TQTxPfY&DjXZV!|J)oK zfB$~^`$e&vgcTYl07(jL_eMaD#f{^CmmUAP$*ywr*JY+t)=N^6g-(za{e}H;eabj} z>d@zaP>yJBas5Gt?~}PsoDZcjDV1r@E3(6FNZ~AB_bt{g>j_$WCb-6|woJaoJXdSY zKzB?i<`d8Gw&Cry@pdDITP24NvG2?j*jdmpENfWyayADo#-&Ru7i-{E!>T*Ns%z04 zR-`x>zBPRN2wK5bDFudMcZ6YAsuP@Vp-ymaSanBObsaiEImd2;PGIh@#Tq~#AN_~_CPOho^&8fQCGteu@ZP?V0llXtU|^>M2K1@c!v!AZ z%GIbZiJvj!GFKaGmannAY@~kdXwJr>Y*{vCW2VOWGBy?&0bnNV2t+aRZ2?3`%_rml z`T)7;P6DaCC>{I2#f$?5iLyW7qkuKcfQxUDI|VijnWzPG0eym{h6o7e5r3l30bvNl zEyE!Rx#SC#*b$K7AIRnm*o0DKb9X8%1`f4-cg@K4fCn1mgN5JdXBe zdVmoRl>xH{rvlFvjyu2$U5*2R?bs73PS+8NB&2r_`ZLxA1Vsk*6m9E16>x`ej1Dw9qdXajmNd<>&qd^F*m)I^d|g zg@IfNdz%=p9gg8jW?2v40&`^zh^nyy7mY27WN^mJ;{Yz=onE}*X9bW?t~$qY(BRs4 zdU_x|bKs&bcm{~S_NKaO3M?0m_<_1GDIPkNb{Tr8=>TnKHiby?wOAd_QLyTB5OSWA zIclUUylp#1gfC?RTvt%pKaoEhrAT{F|6LUc?17ml1yWIZ^_P4xk1I(4K6rTr zDkI}_i>s|s2}LrrScH2>efi}!gd$`Yc#G}FazY+4Zt$8o?+O2apfha@EO7w?DjNZn z)nLj5GB8BQ7nlKoPy9nFCtcyjh*01Xe=Llz3G~6>9C+9dIbusk5N1KcC!A`$lLL&| zo%9GrRb4Cu5VFu)gNra3dYQ?q2a;I818qUCC+x3L(*Pt`8X;&ffeg()N7n=$dq7rp z^;hQ_$&^-KKKZvkx%a=kh1f+-N0(~r@tal-g62IX_d|QkD06Tvc`>_S~+m{Q@r5iG;QSC*$TniW(Alr&-SUoHP@UpIP1<-Nx7QBPl6)Swz9qFnKY^^J5Tb~`w>QWdukRxYB z9r|t1_kQnY#^>rv`?H_+cs91@#a8=~y@Voz>wApr#C1u?Z+K|m&W-6>S%c>r!SiUy z1td9ZfOf3FFrZ{ik;*8sar9OcGL5Oqkvn>^q|cQgT>(Tk@zsnyB%iK2*J*v79#C&y zb>zC}^i~X=b;sk&m)j2DP?j2lLHmY5a@mYR_XaI!T-H=z&}buQq|Lx$7{sCq7}|RK zQtRq$15+QEwON>2j|wK0+(}=Dsrk*-9NpNkiCH%wTW4d|NUyendp$`8;rAHf7u|TR zt-_%E#!-G1Td$>{-*oRakE|QseAW8iWcRgV=$71mEy1}**?-mhvH12-xKLOLC&uspBqGrRTvO$v8k-Ano{H=Azu^lsYZRmRZAq{p$gz@*2!9X z*MpzqtChh4MRzzl{hG1Bs<6=xDMdcF;&SUSivb9I7cthTLux?Q*q^Lr`b_(4#)z$R zlRD=+XyC+Ht<7FKK3%XiE`{?IdK8Lceg_nyQlgAPv~LR08;CsO-=IaduFHxV1!yyo zXz|!DxLYlYm+ljcu#ee9XcIKq1xAkaPe2Y_1Q}n~u65k08JpG#>Dr#Pe7BMEQ-aw^ z!+9M??I&2wo**Z5*MXfCI9}+HgBYgB*+7rFV&a<&Qq&a>vyF~Vf04dM%7vNG1{1or zkjAYXoTj^Bn`Wuy71&aEZmZ&2MT}8c_f27a9p^atSCqY_k*=CAWz^J-sHp*QX5?1D zKFBDnvvgTNe2~fLQ<3baG1FrVy`lq?S^tQ z#N8@A6F)1}&}vYy_AGsVO{ds4X%n=SkYP}5-%u^lZ{8Dr6RVPQx?%L92H!T5v@Qjp zJJECsQ`f{{fQ;7QsEIEtOe~I-CZ|gp^a*DXdT(Hk7y~Z*1}^_ihVKb~O}xNGyeX{Y3K>Az2%rd2wh&PK zL5A}Fp3K2&4sQiYq&ZEKVx6ugo8BmC(`b;^ z)F-V=FB^_gfNaad{+^A__w$Sn{Jg2r$wZ(&&LI6ZkXL$L)#Oww0k^iQcjcrQMQ;xk zy?)mh#gI#=T^1R@Avx`XJ_*Ne!rjl|7>u2@%(Rtvy11arzidA7w3QLpIr3M`+o!d zO$8lozjs$l;6sOO^2Q;C$-^@)GD6907qTE1gWGtvI#|m z$r-;JJh{cba|y1Knnj17#Hr|n=Amxqe|P`^#XcW_&bRFFTh;*w^?f@Ug{~WQrmNn` zFO3fP0yqtQ8(f^qkJ!5jM3aVhAT5F^Q{X_U5u=hZ*q(eBW5X^ z>?g`Ta#3m-H$D7${Yk8HA(C)I%REzLA8hlSKv|7}o>n@amHt`<5|td(On*p?Zjwxt z0MggjpFqqrfTBM`#JIA(Wd!nY3MxaCMNu|^6fp?_ww!Rli7PQ0_{2eSdpx8ojsLQP zkmPwyv)SXpXh>?^-P{L>e6#Ezyev7E8CPe;)m^gCn{7aU?XDrlED0w&1P7w?vb$mu zlISkiB{t;EvQEU5U3Kgr?5w-P9{k*%{_5vta~myY+&47t#dFF!0=4x#SDuLNb}eNv zu=W0>QfeM?cjOo35jve$5zCh{x>$>JF;7n3oa$H_fuB}AobnATWvc6o>19=9H&o43 z@#fmu<11e&W~#n-BTGUaRvMFH2jQQBUpD3D@~|IYRd5iOj87%Tf6ERv2o2%W z09|z^kUE`S(v7RXItO+Teo1;`2VuAKwYyG$(genFhT4WOYX{+DW2_!o3Fgc!u#U&K`k*g~LNTGZffn{c<*AF>|kRZT8|z6&`sHUhw^XDJ4&zqcKR zx5L_Pio~Ttr=?(AMT^1X{l#O+4X<2}F#a}l-DXIfD`YTu!x;R2uGHU{fskQ;T(i+| zji`-$4##@N@DaeA6@yDiC?Ak2kb=z8z^`)eWI(Hb^a6Yj235e7Tcd3~nNcJ| zLo4i$h=HoTf-1oT(@(5v7NKkz15^g6Ru5DHZKfeB%O_NVQ}S&fUf*$qy1JSHPRX)t zH8$x~7--sOX!`N9jgT`JGQ~v=i5(&dVT%rreAv z5jY~W(H()ATL`0D39GLvT-kLKb`YjSPEwZCuLY#UMvNf=W&xrY`8EQ`MRza`qe*M1 z-M+)VO%Y`1APqgXgV3@^%!+D2jwMc^U?HYHmGB*v%n+KCA zt=^)mp({(xwsij`H~=T-;1~@0{qj3|3zDjhXkA8xF(!8ks!cMQ%(Gnn7sd&NV^o{{ zWmf)|)6>DpAeaB;{Osbn$^Wv6=V504muQYn_7{`=rI7vQM)3w%XYLnSaXt^;hu251x1N5yIswYqN1zfh@zFAn9h&cNU?etlsGE#bDAnerTDQB4xTWfs zVYbYIcM!W`y;|~+c;XXJ1Sk3&5Xuofii#ioL5A-W8QU!RYY#*SX$6o^t~$rjpIJ|S zeMfB=KpXSvqxbWB&_C**CST<5Pb+jhWXO4(PG^ophrWxL;PeCS^10H5+Rbj%l)hs@ z+eVC89&ykE(EhmUd_d6o)pw`AK!4i#s&C|LomiV+XeGoc0rMdLv(RTbS&k)a2up$! zyXtTnqAYcVU7$+vN_|YNaWT!JM{_sX6mx7tcbi;J8k8>L`PnLmQwc4P7`tE;yd6;R zet--)LMl@v^c=vT7l>)-$=&?jR{hZD0NGq!*(a1J5C*a>?1K>rDRAJF9f8*>KmXiX zB4!}bu-c_99%#~K%QZ(`cie96u`9L5!FlVnN4=i`MGm&PTPajp`h7#q*$s?=ZU_MAYr zfa?=r$(HNXX;lkzXtrvl07%hF6kOH5C8*tQW@e9XMOVKD!t19Vx zkpEu&)p-lCi<~dl$ajQn?aj=pT6fJy`NC^yy3}`jQikkwC&h(bkQ$kpT9A^qcYt^uhC^zS^o;p_!{XtMwJ-nI>~_ zN`W%W034E#3us-IX-#CImfje9qO*61!ZC8>4V^MtGk}bPLEl>? zTBkz-16;MmTRntj^k>j|J#Z&xA`|cw-*lNK{f#?HsHKg+6`>opQI!0*fO&(yOa}ZC zoXrIpC5zmcUIrD%A00(_&QN02XpY5`Q63(E|GJpzKoD!G`q*!qwmBxw`?P-iQ|E4C1s)0M(W6^MLH z8lAgek=Jj?kk1dopy`Hu>-Il`B_Q) zzfF8jiR+4bpby8ng8=pM|NZl`!D%-B|8y`oJ2mnDn|K<>{}<=j90V{20knevuM-CO zMe&E$@q_Yw3xy)F2dD#%x?6viptvH;p@O|RR8XA!lG6qH+OFjF1;QuuRW*)bx`v>-m^0M&qcgE``0Y{ z@BHNXMIrxJe_;0iHuB76|G9`8<8MEWzlPbrlJUuBJiWY{VYn!boQYzGQT}w@@Y#M7 z(nZ|Zk9%c5x`;1sJiaFmdQbQV1f6L!`%y2k+a}~z1;{=v9-|{p*$KMPr*bk!gaVIH zq%xTd&Vh&hkRx{VbcF_{=z~u<)tEuEF$Jpt%p@<$S4z@aiyGoo);96g5I)RGTir`u zRd-5EJ3Up0e)&RWh^WrOZ9VspqrpUk?oLGLeA4@qSnu{ko`h{Iz_mg~hHs4w$4p7@ zXf}n)&4`DOL&V2u)quDz5y+^h-p0NECYIL<9q zC(dut^r|CDX+wO3$+6Z>r-w!(Wb>=edvX&|-}xHf8idEbRK*W&(X=N|PISTIUHPl? zk^F$(2-ONXKTM+=DPDz~Fk7soFSbiU=V(mG*hNz9$6lbWTsRaB9%|XwxkP1jbgIVqyaP@|M&txG6Jz$GRt48cJ_*A?sIu2v9DzpOZ})Tw!0HTMp;J6 zTi*qOF#~at;<0~4B0E^d*P8LH7CoVGm*Aw%J}xZ9w!%^sF~(NjM}Tq> zzjo31O{mgq|Afbr#s+h~paG|if>Uf&3aj>KJVN%=b`kjTPE-=bx)62R4uTgi_yh#X zGR7_fPBd)-&?*5cN>49rxCWrNVuLzx(KznqBxSA=tGb?k%m9bCLhIs$0GG%QfFc(& zo<%eXVDWVUmr*w?(GN?#ZpHnH6Zc;huNioVKU{VCM=xGtlQ80@YrT5Fcc+pGKkR|v*9P6IYTSN=+k-7J!@`!_rcIHjN38u;@b%t+1cqCAjD>b3mg?Mi|K1U&vYd z#SkyX-Cia=Y}LDkvA()45Sr^cwwS<@E9Yii%N9#({id-f z#Yub#8Ru?{Jo!618w*`?)1?u;M)VrdYeer7qF2AoarKgSyACNE(Yt2RtF9GUPW0B) zVMOo7M6a5Koe;e$t@@mzmlf$>M)XEW;8&sb)~pYs^%~J@M6VIOM)b}Sy$fl*jU}(q zdiP577ObHU$Vd0ko#$TgnbjBpyzvdkhLUyy85lwAB1Z*t_~>39@F=m~51L&0t**|_ z#9}6)nB8@|C8*-Ly4%0S&@`txE2xtzxf}Q?Qmn9K1D5KP+*SlHtIxd8TuN;XmTW?p z(f{`pgbK>ZVjxssjRB#yfl!Guy>%c|uo9L8p(4#QKqxX1mH?dkWz%B7nMs%doSg!k zii@LM#B*0g%?(h^^EO8>8?f0p*gR$iXBY8D&fh#&(BRT(og*$co}=B8p|kEgT}l4m zI42S<&j38@{+E;d{hue#PfyNF{@+bJ4^8v`CUa~u0Pkl8V0lP6S?CR~fJq9x68e;w ztgX-Gn=rb`=DRo9e3LnU0%|YuEb{-{rbkjma|0w(WVg+bQhBkwEmEv@euE^b<5A6$ zgi{~cI7wH+$}gD7u=_UKBc;sRVxy#%o{d{3=Gnxv3j43>-k12PxBmu%^TG3+{dazP zZtTB}JWcICWA*K))mLHH<^5M%ZPFP-ZeI+!67#L0Sr&2cFPM3d+YPgEv`pq#$0U#TGT{Wtl{? z+1{+6qsn+&b5i6kI9OK;W6Z6H=pIO$lY+^jNGb^j>A+gU5W8vS;BWp?Qq%F-7Xdkr z&pKaw9j($%uk-goC;!#K-EaNF7r#F{QvY?2o^`t2E_hje8$fQww>6TYNQQ}<*quGU z=BTIQH|L4T(@Pk<+h{~Y1Ol(F-z6bsD!jRPJ-{Dim;m8%;nz5^QT74>^f^EjBi|Or z)qGb7sKB(9UWlVes|&fS9F9CKQSUNHsof-Skff!ei19euo1#BM#5l7!;m}piP#9p< zQm1DV2VMQuIX^neB$irJ65cdT)gNToOO2JTCPR+(QJR;Y$D|=8;w9)G^(&!QmppC7 z-5d=Dbaw}ITk6AJ!2c_+)JiskluxME16=R_J?WpHT;%<~7yakP|GSB&!v9+`$HoI} zJiyUv7u@k<#2g=xO{lYlkv%0WY#hNm>Ig2GYuy#Btk{Y>#Dr!+LJkh>AnXCJaMP2_ z@oEQQl9^W1pfl}udZO@E2Rkn6q&h^b-%`0yE)zxgQYDWKJyH233%$+hc$Mq7T$gQ` z+Bbu`Rp@>d3^f3U0N#x=ER|&@7JBKg5wA&GZ4NGzJbLw)|!Pt-lgcrx#7arb74Vvxdb|cGFD2PIo8Tl3aI)j>X}XU!3q$SmC0j`hSS>4 zX+qv*ZphR=N4)1DkI%?4BUaB$;vqEiXSVWe^*@B85u&VV%>aB? zQ`u{1Pmr^kx_&|4TZ$T!TwmFZ3x`c>(p`gP7iJc^`BC6aliKUoc~oHzSIlB>>0(cH zlRJ-b$gN=P!9QeAOSwcUAhirqsK@9XyTKq1X15k57RMfHqQyGs4%uz$-4{A^j=uZC#6Nf9pU?7N$2&aw?u#csLh)m_p7AWz)MaHi z4GZod3*I9B3^qGhG1{g5cl;J?bfx29BCj{li)_VaJE;(rDw&reTIa`8WBXBT}F|FemwN&JtA{4tR~ zC6Pbdn$jnW(I(_)4?=$A*w20L^F49UTkIlrcJxL}>Rar(*dKoiW}k+sD;?1>TjtEPo3K_PJI7^5TnylQc3n5b@n< z`fei2j!s6M{3+FM0gSiBfs`u1MI$cdzXCwPPaq7II*=+xSN=0f#z?jmRUZbrsiY3r zXrqZ42qHv9M#*83VlcGcQhoHi+u#?!RpBP?PBtK z51gDmyXZf==y$>QNuuw37xHZi9Z9g>ytH0jX-#A@H^oO+>O@_76lcmn=%T4Q3!TQApj%Dc$>6>T~Z3F5P8i?fzb)JK_}Rr9F#^W*t}Bk%Jm52 zzlQwRkz|s2)q;F^qZk;)U`6jSMoeSRaveZW;3CEVpFkg+e_PV8Hp6_C z>Hk<5n-?7k%AWRHlLTWXMaK9xIBRg$;H<&fDx5vtHJm*)IQytLYYf_b23q-PVJ~;K zv;kQIvU7th7Nfv6wC^oHE$!isy1dejZ~4(0QG}MqWchJXI6hm@yS*?0+rQ(Tm2$23 zZWqWgMz_%gj4ohwf$i1>*0SZjR)t_E^nsJd(Fcq=unp>f@eS;=KA`!HjG!t_rupnRF_kk#K z${?~|gh&wO28(VG1d(gkg^UA!Pk@L0kfSB_NT+)|dyMZZ3i9x1)My8+e zc=A5rA$dQ7}(a)&z^0Xv>JfYi(ZND&Aba#jQ< z6Fi>yl1GxJqL#vxM|5P7?`FFux->>y4v6g%h5#oD0mr*IdSg=5C>S4A2!IiIW9ni2gG-AQ_*Dn}Z#=n{A)Emgf#5?IR9 zxJgUBVac}2CGgc17|bPH>v-RY);$-kuU%r_-rS=5H;5w{w%bUa7K#}mx^W>Y=b+)v zH)cudv8iu^;S_j;BDIO!KkA>eBk-foLW;oqkJsXDoA@I<4k>bgO(;b+cc(%q%dF!Q zvZ^R^ThPF6(Y=%9BTc?4GQ~R}eyRCJH^(0OY?0B3As*ivRxVbhbE7KE%Rv<19n4pw zyy^nHEZcR?T->@upT7r(Yw7g&jkd}QG9Y#LwCfaj86gH0_Z}7B6Mi%G?Fl75W=cFa zMaFzlgO1ydj)F0mK4mq4xF#6%31=ltQ-H!^SF7OA!@foC5S8*@M*>mYVjS|Y4hAw2 zQ#!V2HF@x}v{hz+>lGMW)Z$2f#k3krN{BIdvd?((;nll0Z_t=Rr>TLZmoVtDar6+w z4~Z4MAj3mF{TI1awzz(tU82~ZL4VPA*GX4t2;K#n4W zXaK1`LJk9vbL5Mj$W#{rVGIx5DS#3q0lSAQ%6=uW4YS)(hSBsBIBHCNQ*>rsv}~MC z$F^l2f`-!_Z-?01L8ZIR(4N~KIJI0cW!`@Q00 zb87tYO*yfO7cs+abLmAAbpRMt9=9oyN&MgmCW>+S7qh}V_~kw)29F!VMb}7F&n|DU z3?q(JobLtOyFk6A=b`i8?Z76DRn?ciT%<5&5CfDhTnCnmCUZw8(}_{`Z*K&~x;nwn z@7_-yE*94-{Q(6^fdc@t|M*CWG=6H8+h_WnZnPV}NqkcXtciCzeeLe^^y#c?<=VBV z?#vX$cSDl9@j$WCDea3j5Q>Kr!;scE855Tl@!S3Gs{24YaYyt6ze*$%2@P}{z%xFBr z-u=k=0s|5~;KU+(({5X*YnOCZ_jOI}=Vrp}MpS?Vq{DhHXRU&ji}}Wv?Wvo6ScFFM zJ8WNDF9jwTArddAc<9pp*8BT|1>ypx(H=BUh(SxqAkYUTma)N!mV&`v|7200+BH^A?9j46TwX8!1_4`L<_!h2&!Vhx0^5#3_)oQ@>4o{^ zxz7-9kq*%M4Hc`fn5yas<&-*#O9Xz(RMrMRpt)J=hLl8AZLKPk4GYZ(h|b_n+U5W6V3DLU)UWMLlo@vi zC*JW@2VMHztU=i4z$jd|2QJzq2XsxLBhKi4A8;$56Tn!-FAQ$9u7{tk&f=(u==zDb zKC*nE@WAz6vi4Flei!j_4TU-6aBhyVMsoOBTfCD(OOW4FqR0(CC+K(dRXP)j(=4u1 zEy$}i4$$KfJbd%mW%aNr^Qud?iACIs;A$tv46H=S`rhD;lQB~jhngtLVxLU zek#Esd=E4~g#NP!zoKA$D`HN298U?Sgmi~}5m{o(Q~$LoE>D$4z@@`pD`buukb^L* zh^bPNP$|_Ml8){Mu&@^Xq+ip7LJ&UEPC?9v?QX9WsLtDeNR|E~L6hyj3xNJv%*I zyh*_4_s0_%@sO1bk6I5t-o4_dKTA(aP({5H#4u z=JCH$-X%nPf|E+~-Kga4ml@EhwY-`3d-gKK#f_xP_y0?f<%^L)_(fzz{P4noS2*wx zR>XWHzl~Ipw1#>Thur&RxGRF|3%>p8uK=wWP(K&P@*zy{3&(K$J5Y|tKujlX6P9?- z2>5jO%UAt7BCH=FlR!TH9Df~EiktTct-u)32*~wDvN9(+T;S`?7w~kMWInRXlt>4_ ztn&?aiGBeJCmZesO;m{~@_E67a}6>aVKo#1VZx}qPEYc@L4PUH{2(qCQ%N3NoUBk6b;JJy1xUM|kU;#KcT0Xsv3(QgkVLHCw1kWzW z`yX7MA1>0ACl+WOwNx9RlDe~V?JeNlAabHR-+t*k(kHwAxgP+ioPk&oWW{*MSvC5R zz1qr(gUi@Ov0M{Z1T2Uc>j)YT4-nRJWq21dDv5Lt4w(dZ)ZV;;EJ;QTYda%)6WNr& zF=czSH1QD%YYbg{exO6dhRMJtObcbJX88UcRi-zwj1U~}aI0AW?yuoe$0-jC|0@%NI7uIIDnX+$Th zmL-iia+}9(s)@~MFGpNz{w$f$DH&7`wg|wk0}=#Q2j8+xf$(y2?`7QY*AK6!6%9a+ z+r?FYRcy?od3Dd~8>ywBY0H21e%L*$!Y|Bb1Tj7yGv0cUAgd87@Uf-<4;nk(-oo%U9 zY(wP=j=5^Kl@=qO=c?0;;tC^42|Z5HnzD4Farw;n77htuETbn)HSyiMP2JZn$4SNu z7#t-oEL+>PM;4}4`kX{yx0w`}W1P4#Dqwhp46z1S{TdfO*0(sm3dY`hi}15(-U z_zgh!j-G!;?f)~)&_io_KIHpMsRTxx1i6*oD23i>7sefjwmxUHMp@|_hf?2ZtC%YV z88+FPuoWCISc!We&- ze7_hoo;8f{GJ$mjjd4iAm8D-+@}jIPt~0e7?(Ocawp9fthw1!b_*>3Y8RtWRYqhY} zH|CQsamgs_M31_q#~v~D$K+}x8Zn57vNbh z*(fVZh0A;X%@1V{WJ&rSv|Ku>pSUu_`^EnyC85~2aY_^Gss zU-NL+Ym2Q_cN(8?*ej12ZTlLBs8eXlyH|!gB<|tk)!`*XWb4Y9GhuY@_a8=B#k$mj z;DGs(lzw?{C8Fv4k^DGe!nq2>1_#Z}=}A>X2a6)E2R6i?|2JV2xg}xdpN3?lB2DUN zgI$n#29#tmalYlwRFtixjOmFjlnRU$2a6o5aU$eG4Vx(H8J+mHv`y3gWr-8KnuX=p zM8>==r%C{cq68t+o4*Q5N$DrG1ChQ6In}aJb0Gc7&%$Ktg6t;zWmvSF$VrLH03X!_ z*usQ$t4AT%IVF{==E(Sxhug*A!odxA*@9$-B04NnVVARSre!90Gqi87QluN9h>CAp zt;G(qjCBcZc*ovhV~rBQiF{?!cDpP%MQ2GFiuq0j$ptSGt4XDZHfYh4h@wZy4ctJw zoaM%7SG)o0Kc&AeoSKRzI3;cfDm=T9As29(((Fsw^}$@L1*mBZP#Tnyx+J%^u=pvO z{U4&0UlR%!&+o~-2(a7Ez1uy;#;t2Ck`dlmLO*fO63No4q3^UQOvMT^ff`Hh`9w5v zKJW?uX1d?2+oj?Dv>JLJS%dlVXic;^$&rjE<>Qz!N316Lp)PlcD<8o#mZXxK>cK4xA zIw`(>aJCg!7S9U2K&qW0YHT7h-P2t;e#Q86Wx$>lozR>fxxu&`(98YF9##lxtRB@{ z5kM#~K94TUIGht^iy8c_UnpnBDc6!52Za1WKg5{gO7|XPf8q!MMM(**1tz7}IwHE&# zGv(Pd)qqk*;t=CGV7S$ls6f6b{^}G$h`P&Ts%c4USL^iBXpo_@2q5^z1ZRckZ zNcMlhllp6Bl~1=EmPG*k`TNV!_%BPsqhQ`DaCgblksFqdu7P=pf7Z9p<2CdMyRJcuq@}^Ttog z8?RQG{5g&m4sZA^eI@ekb5^Z5Cui~}cR&38b@C0m1bt&`V;HOp(sp8k#5`4pJ)dJT zTvdyBK+Pzyd9WD|O?JW_bRH3(h27FhI^$=VW=3u=%q(}l0`8*U?~h7a>AHMh6$n}p z^qg#_Jz|aioI|T22o`@IPgSPEQBZ;cDQfs26Fz6sF&KY;$We?yPFA=S=}?4?*PvWY z7dpYUb~FwGPP=U4yt?MohXq!qlV{}?&`Bh>c zbH`_wO^#JZcU@Q?T^hZ998O|as;yBCXe~)lnb9SWD2h|}jftkMwkB*{8MyI!6RI}j zKt|Wv;Xb;|o8Y#zrJ`hWXEh_5Nslp~Gy+aYW;oZBuIR&=hH&7z&PQBC9E6vpc)_heme@c5Lik7VsU8Fceu~JasR?%Zosk6$85V7&rU_-6k0&Y zkH9nM$`$Bc{HURPqp%AxO)p+9QD19Xk72;@a`H`#C%my#NR`wM9D@)ZiKO{sfJC&T zNg%(Nle$w@wl&D((7b)hKlP;QiBlsuS`W*TlVZMJ^J4SI^c(Qd9XLlKYqyp0oJCOn z;#Rr9g4Z<}bM9G-E!mlft2&?HyJh$Mx8Nmc3?mGc_zau46a1ftXioBic(?#_5^{`u z2%fAJDiL2gFn`ZrWQ{AL`MR55^hfhL);b;JAQ!u#4BwAJ2YcYDR zd8c%`e0fZHxJ5Xvv^OuQttUj{oSiPjxtda3%3@Q-K0dij{Z_AvTs&y$Cs?Vz=-2s) z`WaCN7E4MB=WH|QZ1PWM5b7cKJFkj(a2BPCIkh+`vI7&cbGskE0>x4xNm1@ZS$Luo zTj@h2$qq2EH5)6ZKor*^tvOLt6-@Fidh$=e?|w*fW-D+>MB$|{*7W)-^7c~6w)Km7 z%OcXmCv2ie4e?SA@$IWLhLCrlrv0VsL{s9da6L>f@#;l0RwE2t8CL2XOzfL2S5^%u zua($d2&`kni7$`!*r0#Pss$VTLEmd$JJ;5-bn*I&&{pKmvBcT!Iuy+R`UnRk10R7q zjsuF8!VmITQd+oV>sY)}ie>EbNooHLa|rL#pJLVhXys3Hzr=!7SSfl1(zDSKh#9;p zJyd9$ z-~$E=1Wl*t<@z420o*|*@#!fDC38@9*#?9n(Po7(hebHB($(J3TKo>0hI#%6)m(6# zGt9|D7HkPf$kdA8zbDQy`5grNp2UQ{_csN|#|xneNkEny@38-=xX3x|n?d|f+yO@3 zZMyzx?YuYElSDA`7{D0lzyqmY=xyBXe}Pn^svCI}cS>6yu)OH9zHl3-d_yWJ7ev!G z!lOQ@IVV&rCFt4iAqf#>PZp(?^0I?{NhP1MHnGl%Pwj%a(LXSUjPZsF-QJ-UIDh^^SK@&1Sc&JNa>C$I1;H^4)}9)I zZ4((>k=7HtcXar|VPp94*aaBA^ z9=?GAA#3yvs%ajOn!-Ugy=e3zXrU`r%0r!rTr&x8iB0kXahHsuNQsof0HI44QnQI= z1Jyo`Y5kYDI*}sC^gY~^=GXF`R4To_!{n|8d#v~`yyc%pl`+Fesjzm*yQY`yW*emSqk8jQv2#=ie^?O%`@`V)=e!6);LFst#8&D+Ot%yfgG^tX4 z+JpY*jJyEdlevY|Gn_6|8YMI)9J`l^7-QptCU_FMsJ3d5b^X-~!wvC?e zd5?%Ozl`0C-Nz1aXG-?W!UTy zljfb6aVl$qqhdPcF>Hf!957Uo0;&K*rY+XU#%6aN}-EBM(B^bCB2hNh+m( zoo$IHaB%f@*Jy*y%nm=kjaH`}xYwITJF=9HtITPCVLYjme^Qf^wxm4*gC2WjE_n4$ zNMi~@zwl348+``|qi~|7 zpNnbglhEFne$a@{fpq(TlKZN_KNNG#&!5y!F5i-XY8#E71Zs||!c`Wtr#1Xk*H-X6 z(&=!;Ad-x(K9F;Ye$P~CRPHL8L_$1mKQUMJu*C5nL+SjugH#v`%1tYWH*dmDsYnbb zq^8$`-+aFl-#_&r-nSGLGWM8CjV=m#rGzWy{e8O8Aw~E<%LAUe&Ctvv@kF+iiQYV| zgvJT!bZq1gn=pL3E8hp3dwv7f6+Q_<&z}6p5-0{m+g2rHyoGL_eZ1TQ6%yNQHEKy7 zl%#u}215MT6+enfzxjS}56%rL@06=(t>8bcL=0YA1GQmZ`hqbv7tf*FiOm%Lp?Kcu zzl!DlZP{!pZta)wM9tV`gP>+}T$*Sn(Nw{H#fs&zMXYb1$J|MavcfhKxp?AV`smB2 zZeCoO9XjRWdTOVmxcP=*V{lm&(-v5%jYl1@%n@Cr+!bn*$GN5OO&@}MVM?j0aL%oe zOzL#_#9;_322VqBsrQ|uZA!`(SfW%4!D!xTB4NriJJo@6iLMZsbuvH{1hkBTqYp;?lGn`qS)wPkLifd1pW< z_MfHvjdDY>qUKE4Wlo^4SB?;tB#uiJq4WH6x;0G3>}3*)f1>+0eM?UnLf6^a42C)u zv*)_>3QHeULk~|4yb;p9C4;u0>`zQBuhDh5Z%NMI3i8>#pXJ6X?oqpzjDe6Joqgg+ z;+$K^j5_&SI&t!WYNk$qtx8=94@A3jxl%Y@0rN%R32@itQdAyIP99tX`& zvsW(|;SG^$8wqBTnJrvKAUWEDYwY3({qCdajjI8RvPW37g})~fy}1^DjZ%_5SQqMz z|HD4uNz!SJ>`+|{?yGD0gCds*j|@fbCffny|o2KUK>>sb3!x6g!F%a_Pf z)69_Ia3|PY;OYENpM6Wn!i?1Yyd+g3o-0WogoZc^yg?rmpv{ zC>HOqfF|ZiT@k!_^Bz+dric%tBB^kpvbRv8mR4#}@9u^&bx zqdVHQe{Zg?QLDcY=NBL|wrJNNt26Cx}%LP|G}Rga&2qGCyHQa^&YioN~EW{IQxUq+A1dTBQJ8W-Vm zGou8QljhtHY|4Y6DiOzCrd`7i_Jo{R4nI1DpVPx~AUh@fTPML5{#zFL#x^XZG6$f< z){trVTuW7#c)`T1!#U0aFR*I{z=S8J1D$-DA)l{A3{gMnG8#>~v`GDfIEf!>4+b@@ zAwlpyATU=4!c)SB_@o?7Cmy(dgXrlYA@WW%<{kb!wTvlThHeuw zgK*iI6`Xi~3TQhCRM=*9_5CcY7A(!)Dm8tAMi+umb7d%TND19ftgOYRj)X8ITJMoW z^+ubAM(OjY7o_2dx0nqOb`XZ4M7WhZe4Q)xWz+Zsmu2|bktNdUQ9!-Fni1>(Bz0BwbuYeOa^LM9T{4I9PSm!>l6wDvZNa7(iI+YZNB2pb<30mAo@TNcK1B$ z0JEn@P^V7`^!m0Z6F3EXj$SetEEb;1{uHEff(!^eYFAZU(a z^7_DEovq)Qmc2eA(P5csGzv6@U`QR#Ic3=?R*k0VOqbQ zW%;qTGj~x}u56kSg{_v`uUX51TAhq;D--P!2`W>=6b)3*fsNVHwn`(NWo#kC4qY|^ zF=g+rfDh}R8IJ1eqnNa5g*YaUj1Z6(3(F;nS#Vq-WWTod@R!ETxFZ(FOYXMNBgwm{v5^9}GPHgG z+`skUlfDOjDz*Y!Q_OY0@-V}+7}=jy!Dd_W_WlwG%4KuY=7w{*9brziCVP)pkD`)V z_7i1ly-XG`3H6NLcXm0sR4+f>PsT$YOn;;e_H{poFo2+W{$OF>pMg$0TM^2PQ;TmF zIL!Fbapj0pm@CVnt{DuO|6|9G#ofnq&m(KlE$M}52mZ%XjEqrAj5fVdL$+T1402ac zZiR)PdbFUtx;!MMszeaCGn#RopDKKSyozlk$aDJ7-H1)_qan+^WHWdn=1ao5s4WQL z$Z{1Wzka>NwZ-#Da5WG*eDfc#IzyCe?wD}Sn7)x%)G*u~`BIB7Z?5Hab|)2(WB?tK zv9o$X@o*y0E6$Zm%rb>1H2Sa{34J z6TUIlQ)K@EA01=nOx0pqq85@FkXiW;Tj9?0757o-BaPVL^Djg05YkGYvU8x3nG*Pb zkH)z{np*H#xh6YO-TEYtZiJ@}^-gtwC&Qv3JZky4>|tcE&vv=7X6Z`w#PW%23B|oc zK{B-ZdE*ohE%PCcFKw`{r&{Y_#`o@NzNwF%$Jl`6As{|}>AfHxeqJ;$@R}oc>1*dh zl)w}czK;3_)MmG!hU8Bc@jAq7RJngm*gXzc$$ZW3T!bg zLW8Ax;nG4h+NJHYXC7oUAR34nOImJA3TtjT!|nMi&iE^!nnNjxs&iQn)ZpZ9_Ni?u zl>t#}HpftYHg>z2#Y#qkOFyhE&RJ({_vy4ABHt;#@9@t=6__oY4Mz zED0WaNB+Y{&wZlAV`lg915^w+wjGS{Hp3%lW;U5dELvi#^30O>vL~_!eb|N*TLg(x zdq8}|AWx|2cDbe;fKj1=MGJsnItUdIV*JNQpf;j&nhp^~8(zr3a!i-DtND`ylv%M8 zjebE&Xfv+;vRHsDQ(C=pQ>!3~Q$46zOQ&Ewr6r??8twdNyR?uVY@7~dIW-VmECeA8 zUqcj}>K>S5vM(6-_r7Ptb2$dsDfFO(8hm(#s*pF)b{41{e(FyQDMC+<@CFrZC$^-Y zGsGkzrpCA|#9+o&eC&b9Ct3JhFw?3JO zsfK}1HwR47BeVk~?S!r6RAJEk&aG62Bpr226gYXUcXU&2Ci#TCt}^s+dJxzR@*eH@ zQ!KtBmq#XhnB7^7w`;^u**sS~dzuyI>?ku?)@gK(?E!1AA`;Z`-O*IFMt@qwS?*a{ zAR7f??RVPJY+Z~8U6z(O-!BYYE)-jsJ}z1lg03@;wK>I9&< zi%a76H$J*_|F1-J`(S^8_(^o9OF>Y?8%oj|8Awx&X4u>eC?w@Zm9Ewa9W&=(*ohT`IR#5gii@#nAF`5DHyBB5pyZTH3!qTd+_bq#iax+^g1y&Oi3# z-2n;lE(qPv0kra;kM?G6@B&E4BVHf73DuShS(2@Ps`zZH0ho{knhfzXHG=fO-LuCY zK^~kK<#PbQ$6>zayI#KB_9 z7Xl~md~WJ{;08cWWgCz1*f^aSIe!1r;1h)>7@fz9KM+J49v3j}IwkoaXB>H!# z-)fJB8u@y+85B+4Rh}VleH+^!ss>$AD^*lnKS`ln`TOIQJ4L#PzL0munQz(ioVw_x zv~y%ec1(tCAbO#sOW*QY@a@aoXT)q^E&c{-5#-{yeR?Hm>WJy|G_|fJjAdcJPCv|g zHuY3iD7{`BqHUq2&ylMM`ppM{nlKwu*hg>;Xz1JqaOw0@wyO3z)eTABdDq74|DCtM zOFf6fo+bPGOt92P6P{m!n2%wTsZl;Y*n-_ zY;VSp<##uVUg5U)$pCiaOb-ki{&3J78}nJg@Xd{Wv1j z8G>H`sQzY*t8Bvbi8@+QC^MVHIsmMv$La9jt?_BiA&+`+t*!bwtB9%JcK1Y{2D-c`TF_ z`OOAi<{+h-8|`z6OZs^o3B1;PSmh@^^s4~Buoe1&anB3Kf(XN5(7GSbYPrxcK$~N& z6Nam%p*Hy@|BYzi@4ihHymCvkh1-13%jCh3KZ{L^$X5rB*J=T+g0vxFqxW%ft!tZ= z_eb26Q=GF8-zf#BsS?ZC^M39Hr(0g%A#@v;HeT?Y-G#neW*i$S@H!{k6fCxz_j-tV zk97chi2-!`5KesZDN#071fU-e(*8tb)<9OY*%s{3c}v5clY7$!j(FaxC$dXePcb8^ zg)?VK9!&At>WQ6`gP@nq;R^u)!2trJwr_kP{Z`9eMg&!cFs*UkxZlle=>q4i&G47J z9;*HkkpK5FfOl1pd+qw-`!bCi|KeO3u(xrqKhoVjZzpX`=i9bEFB-U}|4X6fLDBt~ zwUjr!Z-5vEtAD8nt%QHYizXbq$hG|Ulpjd_4+sqnElK?a;M)eAz4mM%RRiLG3Honl zv@R@lmf-+b9ttK)!n1mGYE&p`W%)fMsZOW^&o8y`3{m^b6v?@l9iOeTe7TS5-4w7J0!_Zp{yrVHgdGbL&^wRim%)ca&Y2=s6}+FncRR@0a$78|VxZ+`p0@9LHt(D}rY=$TEpZpRCx-iDRZ2^+TCaC&!RUYnkPKdd)L7PBq7y zUd_{f&W>S~Z4imkLn2Tb71XpI{89f7%!+0RhSz#e$~IUBgUrwx4otaQJpLH*x=tXf zG+D=3qbSWiN-VcMfl}K0#&Z9$UrHQ+1*dbd5L1URah2B1p_B(E87Vk-)tmsr-Zek3 z^A~_TpLGjBt$Coy%%A)( z!U&S$UcvaQpyc}qbjC+s(d``S3NUx{zD>1$Q4cgn$UHwA5_f*u1eWQ*S>(2-IGS*? zJCWPJsEY=_+UZwkr^ix@9PiPII=^<@DLT*UlbW?&m(fy{y6Ur)jQv{qu!tz)=|-cW zKcJKhj_wxuUp{N;8frB-ZlUvJ=`{XBJuLT=d55DU0S5eIK|}c_$pLxE6;h6dzxf=@ zhQJSSOed2KQAX%vCV$k6Uoc!;e?7`9li|O9VxLru;cmxJh7a7{h!Di2LGz~!US1wC zSb+;}0V7{AYaw zJ}g3biBCmFL{$6*RC)532a(5*p=;h>Da5MZS>mH<`=-*v%xt%GG7h!eB(%iFWLAUs zx+Nve6L$whdtk|qR1O4SKS)~tq1m#e8vxe7J|NC`v$<5io9>s^dXq@ zF_QumtVCa^0F9G_CnD$&Qw}Ie_(^-@HlmYZQRT)?;`fs>F(gSaexOAp5%&y22p2xU zwblU71?v9!z1bQV)zdg9N`41CxS>J?dTwq38*+{vCxBBwUL%T^r1F8B8GJboS&@-K zGJD-ATp63yG^ftS@~nKrHpG!QkEzz*_6l>%*Vj zL3TG6ERUy4SzP1e*6`ZP43Y&78s4lTpGG}%WSctD82uZ?RL{5C8fZW)Nlj2qk;mIt z+s7R29=gNkIjnR`<8gF+wZU5KeuWS7EQ{1mxucJ4ofJYW#VlV-)%RiO#@!r7Ee$|X zej`L)j_oeD;H^`wtb;r<%F{z_FF;9z;o)M&s?y2p~ zZyZq|`8s%W;yx!uL4zc4K|1-2+X3(D`YoY3XHlHqX;(Z%7ErMnk79=IKpV5|v3CYb zv7zv4&jMP-8ogd4u0)fiGsifp(NWM`5!oiqQmRB|gJ<{SMIA_)^3Qd|rA2XkB+>KN z0p9Neko$T%k!E1@? zIl_$D_Dw!FI7zZE#dv;2ebGX<^l8Yy!)u$bnt1!6ZaQVLJ#o3TkwK($&YaaU{_8_MGs12Y5@M6S4$Qk6scM;vrG=x8thU1tDIp(;n!Ph+yDujv zyB5&?)XK-(t!otGv!6@PscGLUVe7+I6CInGSU)tLg}RT+bUztWUStKy-*#S3$Z~+T zE~|%tjp_TgEyg%z;Di}U5C3B9?=AkkxJG8^%Fl8$x%RtU^h{ydz|I2%z4Ne0K z5a^NI4K(+0THONvNh#Y0%Dw=HQ2?$+y8%N&O@oHI!}V95neu<{1fSnle%=Y<16u(v z2loJhgk#H5pcZm_1g#!tB|X}f{ze7lPP*3YRmfm_u$CL9c{lv$4su7 z%jQR0agf?n;Qkz!GjODD;TiZRU!!HAZ)pbO03dBq+YwCsr*Wq)f8x)fb&|3K_nB}& zIXXFJNAVT;Q%J&!y8%FYOyp<0zfqpN@U`ITji5%fHex5;zs*1OJM{FnF?|d#s2{9k ze36DI;ZN|TaVQfpgVVMuj!ZI|Yxi$VJ`mxd1c`81@J1Z}Girv%Yg}zG+Ep7_Pt9?> z?8r7+bO$Ixm0*OD(U^~z z01^Cz{g#3fn?=D8PfR3M$4IPqW|ffW;}Z8})AC(_&ziW%1}6VuuuXyc+J}pIrd; z;diA*8es6^&5>TAe-ZLAX|fYhH#{H#y!Ih+Xk!=YRH*z3Q{;cg^EP@UC+(<-e@Qb5 zutpL2(~=8U=J(E>FNLv0DY#eaw09U~lt*}9k1+okttbbG;5Oh}r049mzR$Z;oSvdp zti>)1<*wX-Zng0Ixwjx7QpD!z?MsPIn zXg}pm5jpeiiUHQ()gKGK@M2O$b`Mu*Wk_UP#D2<<4ts#79I;#pqNw4Ut|T+kQq5aH zGL>TGE@((mT&dTv*2|h#8$;tDX<+-?q<8R94e*K>wHZO{tVMmdP}_n>Y9 zz0=Tb?1Z~jF|Q!j?RAl#{u_4?fs)toHhlRdMX$au5Lr_By8(*XXAfpmi&2x-wk0PW(Hu`PN27a+4ufA z2w|*~$N$7u)7v2up6&J$#vDK!1bsxa6-s-NF6^Z!XHR(-@#%DK2ABlj^@qgx&lWNY zhMmQu(*m&|qZIYT&TSu!{cMZ38@hQHFJbSA59?_pi1iG!r6^MXKfOf6p3YRn7>;Dm zU{p{aGr5N&7uGEZ!!EZ#^1Rvw;4L+VYJc8TKzFUCjR(V+^(c7S9i02O;S|2Wc!83m z7I%xal>!E^?>x_P#MC;C5JEs3wPs_Z%h3ZWc|Z^Z9?im|SP0DScDxHxpZ#`DpWox6 znIKcxNGD4lQpitYd$maF`Dc}N6hF|RYQJci2$w)}wy*!tsA+#~WMQMbL(3ch|IKl^ ze%S*ZfW^GPo|LkhoH{?c$rUGDqhS#-#yJ%cAE@aRC=gK5?c{$MaXL40scYb?(7_!v zr0K@vW67$==1z>T@(rZhaxhz-P-3H_V*PQUlK`h3DxaoIB#sUiy4U`6>+f~mTTO*27=U!=6ss58uXl2 zIJB6`5_ntLd0a+~gnigW_@NOd&CD4FbH$E6E>t?4+1fJ>&(GPxU+|oSt!QQlvg3In z%rYsq9y$)iT;;nrzt)qLH}48v9%8a>k@LvMm%?ZEAQ`am3N7Wzp#*xhdJK$`MMDY9 zR9oFg+jCTH_ZOxsW4kdJF4ZYVRMnn35_wXqQ|)WVrqo}BqLgy9vvx152a?kk9uJ3# zFPbaqg<1Hc0=eMmOjYW82R<+-xxR53o2?&GHJcA#6Z=Z#|xcH=hnT zGWNoB3B-;2`$4Gf`Nt0!R+y(pkrwL37&6t3%yFl>7K1evDB$ui+A&A@XTR81Ff_qp z)Ezv~SI_HGgtnEOO)AW`1Et{B<67IoV@Bjqc3!Lw?biyupu$w(g)7O_F52a|coB88 zf2%;6CQx?TfjeL8SF#c(Gt+9TUH;D3cY2}+3)3J8lu;V0VQ^SR3qd3Eb0#3 z?kRuNX4+8igF7ryo@n0a6hfwN0#x#g8R##YgmTU?ev}Z2PFCaDOq0<5U`|QutoPj^ zM8?LXpF#en#|pc_r3E7@N5?EgEZ#0ZgU^P*ph`(8Vq8!SKpmA;`6t^xL@!@ez>WDt zA_z~%nAa^Tg;Oqgq+RI0RCpCy8sgpU(HZdJj?WFYsxmp z8`d!_<0OV&PmGD#JmTf+1drP1N$&c`4$qSsJ9n?uR}a9)CHo0T7|Z+BlT&t>gn^R1 zz4oEag=_^}$|2Q|LU94A`O?{wIHK@nL3@VOOCRI^0K=$ZP*R3_2Fy08PQ0 z$^8yj(rM8&T;TByawG8-Aty6PkrAA-`zam}hCeFTr}5P>5Xkox84}a{0m)6e++HtvZej`n?&(9FRv-is}3j}ZUeus%`KaIX>X~`Vi zCx^;cP4rWZ=?B~UQi`kG$3f=qs+3**=6oAl2RI9^(TYW~O>`0{?rFRkL5G5ky7``o zk^&H!6EoyZqY9DKrW2a2EHBVW)=ZvK#;63#eBTzW&F(2XEK=8S*-{`yMKD&yfIeW@ z9m~J$Q$_HG3mKQY3&GZ!qEN!`aP>&ygfQo1V6}ew;TbeLEl*b6L+G%(1^v(vj0)Gx zI4@M#PIQ8<+lURktF3NXqLmvy?dlSfyvFrPW$GGtNssH?;IT2_eGD!oM4hn zY+DoCwryu(TNB&1?TIz9J+W;&>3;qBed|^I-ut7g_O4si_x3sW^tpHKwbo9L!wCvx z7KSPsu};OspSi5dpCvg8X(pb-MR|RH0yc1O3i8xJ$-7mhCsgvDCw2 zm(160*`@Jl=j=GBml=#k6Q3*$POMPKux5UVokHAqGkThVbSd=|V^|{Eu=R#>1QXn5 zb#wPaqs}$X#%vN*^m`(GOfruLU${ZUDBY>!%ql`ar~uTkw8eB433q#jCx%!Nw@AGnyjbo)f+{8Rn#+5JxPP>4Rq>j+Gi-#7Xgz$zffiPB znecv97vm&!%mg+{QbCDI`k8d#%V`q20k8LNTQ?S3)y~suzz+q~XPS4*hzvD%gI+y~ zX2iyrzu@k$xY!#6T*B?P#{5-Lap73)6lUZVVHNaq!E;AtFp|O!QA;pk6%Zn}j{N4- zAbfjVzu?@Ztc~{eqLnXp6+!clcAs3-Ij>c#MRtOjmZr2d`!rrn?JL`b2@krO7c8BQ zgBz}Gsbo}*ja(*Wr38AK^)JZ9AAMC4@oCi6im`Nf8!{&v$|eRYvhVYn~D&jOfM z4pmZ#z1hyeX*O8W9+qzEf9t3o!>VXCrC~MCG~-(j>}EdAPt{X#yt&L?T|(45JA07m z7js}VYZpJS)%7ab*KIb5enfqtOXPJ`5mjjg&`wayF}dg;_1B-Y=*0HM&H9RBqFSo? zRAN*?_-Uq5Mq-3WmA_~JGH znO3VB9|`Om^{$~m*wRWU~Oe>-j zu5o<$_jh?1QdHsaT~1;ofV{1OuXQ%6b2-di0ec09-Xx_a9X@UMeF}=|)CEG&c;Z!% zIUlI5J|35+xcPbxGoMRcF*fM`+QHN-`EJeOk9?_CDAtvzhOu?NRttfzP`*04iDq;x zk3_2ZgZnO_qoT};zJ^skd=Ns}i;eJXEqwhB*vbm5D5nR`o-(5Y16X;^_knG9Y~!{~ z8i4%Q^Qd3Q1qgbA{)xdvgY%n)!*3pIAvNS2ez!-qtbUV_mcJs;u`F#GFYBPXG{2o5 zutp^R>rUNT5Zrz{2B9JgOVS&NQ}rBUKhW6i=%*Ko(=@jhuT^ycu=J-ZQ{ZaufR9_Q zT;PY5@9WYH(2rEn_N4DY0Gi$tPd3U%n-as2=)C$V3@g}+&P9c#kTaHB{%5-^wUsTiZ<(AUzpif#i39LQ@qd5S=Qo&|^b!KE72^MbbV$VWf_~1Dz4Vh{oFSR^ zr-Pe>fGN|3f;H z8FHc_2omH#8ms315eYe#vFU{wJ5HY|q-8-e2>6x*J%FQ+ia>qn;x-$HQnxLmHEah` zdyshXmt&Rxiizq)!AT!pZkUWn9W%8V1M3vIOX3=@n}Ny^J{(F-{~FGILwtS1z$YRg zz`p`xHkV0Uv&g2zI7mVTpg*JPvc_Rrg!KuE7ykKNvC$zQC=de>5fbE-90CXSjQ?XH zmHW~a5$9^8NXyazcNVvGQX_C%Wo*h8Wz==aYSV(2M7(SHlqj-9-9B6B&bC7TGQMk5 zcDr0~;*#KZ!xwr`R1!DVM~39@Lik`;Y9*aRnuFTq_$9RH~@8moDqec_Rx9 zVY^z$*V}Y_);ns!COF@4W3Kc2Sl6PhRj42SBOhuoNu&Lbd>C)xLTCARxJc+X)AY6W zSvgq~d(N^k?YMmaF=HojisXr@?^ltHrux-4`WLAQ#bD&a(HC-mS`G?>~ z@grb%z5>L7nOU3yYIY;EeDo62`L0_r^TJ%LA>&PI_G;6a=TTQ1Ab;CpuOZkbmoA+<^fK@^Q)B0P$nvI=}L3`RpEmFIkM(_hs)lEvREX z)OHz|NS*gD#~QTLYq|KxT-t{AQ5W|Fd16E=wz^wwln>d6uGOUGZnF8DF^rx(b~X!8 z@RML*$5YA+V|xa!tc(I0VOC!UW;jXT;~@_gqt+Iq?Kb@#@^njT&fVkUd70f32#yH| zse+0MJ&P}7&%;&==0u>46nsV8xcq#xYMW$-6Poz29kDEP+4|_JM8u6$#;T&#m=g7V zujV&ajW4K9o9zx=RenQF)wdW%Egtsi##=Nw4%Ck`IRWvxRynh{$_s0|aiHNN)}|tM&vqiDfKiXv!JfS%X3D;fgG-mc{thH4!snesjG(JgI2J-l z%>bu(2Mz$Fb%25b_--$Pc1Mkmz;ud4ZHvx>Xt{8YgYD}HGs!R=#t0uw)#!hUtS5pX zS2c@)od;q+#eYGyjp^F(Z-WYnqL_$>T@kD<6QusCAKOGOb0QAV zv~-6!1l?Yv;s+_7gw9OGa_o&Z`CpzoWX+P4u)-ZSN?|2cnc;=+DrMhSLU(kqFmIc` z%{3{)jNaT!y2WyE@Dd?jTJoaz*jD~@!aK@U&Z-rFCY}X1yZ)05WA^UfrGsh1;_$2Y zb4h&nu8axnIXla@eDOrbPvbm*o5+^%D-}e^^6+Jy*#>$spFj55@o@uoq6WT5RAHmF z=s1N=tejbvr6n_oE;I{#6|0nDC*Xd63Jk2p6yY46lFhgAjlCpZ8LW0xnB=2}zR;Y4 zh=T@6@n<1DnHTpiJqK&N4_9)Favi5dBtmOggEY^D;Xrc)swyf$o%EZ&j7sKD0na^9 zuaOka+diw9j)^_mhrXt%Xtq4*_?Bxdr{un3{|Ocb+MmMD`PDFD1Ugdjpf^kR_bc=BZ85AKgEY9u zRoQY-e;@z6sO_AG-4=j=$tS%Zd+o6VkSp^l+Y zh_cALHqR_3b|N%;@e$#4_}nk+6}b!c==x;vs2Ou;f6f7^T409yXU^!aVPfBAYGVSK zK6-SS!F`&@`!BfuypyQK&gWOm(!RvGVz8*g2820{9?EA!yAMOdrlq1U5Ko9pCLhSl zef=B&dhe|GGGwe{@4)%!EB(r}8}|+Uf`F0uO4@6zr9MavSJ+718e1mhuBGyiCTo-V zxW>QSSya^obR|qvL8-KbAt+G-M?b9J0z5rE=f**Wa)t@u4_xOU6jDy9tzJMvj31r}Ghu@sK@nd4-@A!r{Jcv~bu~<$o;?~+Cul)DkrfI7 zyz>pHcfhxg`~z{LN*ME#02D=)dk_`Yck?JTUS;_3qSWuZCyDTOpPM;we&2Bho*iw}wi<3POXH}^MS&e+dBf`mZ;a|8LL6 zXG03$hJO~2D7Ndrf9D-IpyHy@=qpjm-Q?LR7ZBZ3XAekn{|1Gn16KM8BtHPI30}?s z?T*%d19!-pah@%C8X?ew2<63tcN<9U)wkgUuoGms1#W2mN_{Ek18$sJ0;hE^v9RBdS&| z`qbIfqacQ1g?V;C-Ru}s)-#gVNyceOcJr)$GPBj4R(4jc+TL4V4*jKg|J3>n99jG7 zQvhwM4_8r0(rLN7o=Oh}Gs0~suMzp6sS7+!nS*{LNMVAWcm?jglJ@{T7VdyodVcGnkGAgnC&I(=>{Pj^ z69MbHz#;uBFvb<&&yN7uQT@+RjXVcUAePzM-A?#X-_TVHaP+ICA9w@b^91LLXf8wp z+)?}p=zQ(7hQ69U=5E5HwRfvrg2Ug#=%G29();C>i7!S;=>%U#w zZ~Fyidw{=&$hnd^3()O2W|MqJwCUSXq@wX{k~I$FhSzGt?5%Gtu;{rr$uI`MX1aQ> zynu{bfl2VqQ|hQ*2u7J-0nUyY&%n4io{s>!ct2pX;_C#y|3CHFN6el{hC;gznjyl| zT-gg8W{g3Gir1_~)SwUUdrgyDZv_4@Z(>e?m1pC_GGaMbM|BkE9&DXB&Ms#jw*e`W zs}eqVB>Mx!kme(idtH8cvT7?c0*=T;g;%Q>6=U+-VH!}ChXfoNG15Lv!<6fU?{p&z zW^P?lS+%muQjS1|%PGPGK_JiYa<%ET2(6{PCO8wLj0TAXE4YV0_ld2xE{V{I;nFR| zT?~Ki%swxy%^Z+_0ZZKsRAhY<90`~FKl2m^Ouq#l|I^p~TgbR$r=7!wg(Cqr^mpu2 zeN9eV6B&VbQZ%8m(MOBkhbx9ZPPa%MY`t$nL)a zl8?yVI+z*xr78^ieRF7aF_GPax16}btbKIFCbWm9tilPT?}?kFK&s0^Rp#yxS1Hke ziuz_81eF4TeJRSbmHxtmgt-$@M%p@eO|@%lnBXJM-5{*o5o;Ja1E#Ly&H_s0sF}8f zUWZbc*g1MPrR>A1${??~q)%7$bOzA0O#uwvkd;7txo1N@H_&J9C}4Z0IrDV~X0I#$ zZ*<+=j9W&%dukhHlL@;p;4p8Sne#jxGP~bnx4%#?q+dW(L27=P0T~cSoyVvcG}rfJ zsjS{8?jyvr13XAl{G(%MQRxaxSA2+h*2|%x-v4P$u4iLRfoj3=i2I8YspaWo;9|on z(QGNpcMs|A-nA{m>SuL^S-ru+oJn(kr@wWWXDu=$Sd$;%`v>E*<*sp_=MWKG(9+^@ zH#&-bk@ZvDRbYge#*}H1uLVcjB0Hu6KqxNJ0iMRUtR%`zT0UD=Z=vU!p?ZtMVzImq zAQ-+RE--QEsr!_23Y0AVI(YorfrZTly)a6i1LvKSqyzOb-wwT(AmKeS?|-%W?K15p zgMJ(mjyK3-C+C^>P&5pX9nn)#Gs}XG_8hbf7%toA=P}f2>oh z(psVj8$Xz4`_0Qa%uf4gW6J$3@ziaQU>Q6c<>dF~vx2Y?_Kj)2)2WxwxhD1$wX5wdD(iMfDAFrP;ly;Y<`7W{X$bIYG>NNLnGX! zB?Ai-2D4hENK+)LVyBHInMywyIywCruUlRiFd~2oOhV0TNO&yY!7eH{;=_$4HEcGb z{1idnrFjj!ZaISrRNO3aCphaPd>))-)fE;rJn{R1r=xG?9@n9m9W}W*lxlwMAR^#vK;aG zSxC`c_cO7j0pv=}d1onz3jDek-}D03H;HrhItUBxGJ0p_vi?sH$GV*zlA7xMgW3lz z*Km|qq0V*^7sv#C9nTWi*HJnHy%&$BstxwnE}6gLX|2wIxKnp0>a!&d>$}m)?3ulW z@-^>o(iKa;Q;;D2lXK0yKd{5XEHzlN|UoB`-h2ZUOa%<@owuH7uV4Y3iXs{3cL2WmJT)Py>VGsU-zK5X*s1jbW6Z_Ul!*mj`#RiFLA zp>C7Ua+1QRjOqnc0Dwn_f(`fKC;28Wxl1;V!lshyFZ1M+Zrodnh^t=5$!uVjs zCcVa1{`T&RL(IJOrMQchPyqwxd<^x-D7rHW_{L`$GEnf6U&)GmxXTS05DYK33l%8q zYnI+iX3#ElQ)+q0ro13$o-{E{rmuhn;s~H;+^j0qM*QW&w~yO3U3Ht?mayxKCX-U z$tIyy@?HcSNpw*2NxqVu{u3HJBGNIQg@)q<6av(?Jm-gm4bL-gDl8_;eiIj3d|;m; z#e@~BTLv5iRUCX5BOcLz%Y#>c=$y9u=HA@I{;b@9^#0|TsIyU>tG6j&91!y7LgpiW zwop;a&{3O5ET22{yg@p5cUI;_u;dH)LG_^z=&R+U`B0pGEzP(M%DJUu-wXa4+DnT< zFvA!*vqe?9e4sh~g1wleeJ=HQyX?0gZV26y8!H_~7I%63rNm2#&Xwvm60fjSL*!;) ze0hn{v?f1sxi?4ah=3BtaWLzJj%JCELmrEcJ0?i2Ll^2(3BgwU9t3RVfF3MEjd)wZgs~j%1?^ z#2oDYNu{(^F&JO`%hE}XE?$2UPA+Bkw?pmk!)0i?cYfM@Fa)cP%ckS`T8!cde=;dwf>TVJG@_q&RwMIG<#l~i{yX#?RYgYvNtEE|Co~* z0l(&K-u~sCKN|{da%RjkqjrwQ7xGqL!qPv0gw3U20pYMzqq$#gv6e_5O!34B`w|mw z9sRi&XAf9w?pbz`7~UO(CbA_;^Y+pgwLGSXm-(Qs9>c*C{;Czb8jz{RUv8)&`2i2c z2(3e1-eX6Bld}qHu11U(@aie)j=@z$&(-ToyK^aft(Kr54ZZf%jwhNz5GO+WEfYs&XG zmNs8|WH9pXdKPJNWVj*5$q5D|(pUK80xACS@PWM=32Tm(F3I=Tkf{#T!n>!72B9&G zJwwO)Lfm!3J^&F%_=n`^Q&p9~Nre|klN<$Wx*DkAV~&LBuDMfgF0#rkHmnjYZbkv$sDO)@ z-|4WfFc|p`P3Nw#Kt59tXF`h+Q#R>w=5}B8Da*_*ErIV~q0C&VRQ{&K+7@#c1B-F z%fSrm#hVRa(3!ZiD{l-!;8$CDp!1OQX>gme@f)T>;i%^0dS2<}L8&7J^AO5y-lglN zek%XU4<6acy1-InO1e2$u|zPzYoQUYE0DhM@zbG)*#=eH`hUs!aL8$_d%Zn3qH4R! z{W}$!2elR{`7vl6Ql-N38%&F-N;XPQw~B+Y@;B|sh=RFxC8v&chFuKK!EXrxxvydl z16&EbS5z;?D;Z(E0TSnlXL&PtfhXN#Uc%ZX{6+x}Yn{5gct;UGerR{B%Y{?s_&+5R~B^l4*u48Am!$Q){) zoR~0^0T`CH{Dm!zAuvLG*}x**Cmk)vzrg4NVy;Cra&fHl`Q3_JmvnU9`UFBnh*(GW zJiPSh4n1S|s&G{?T<-K8i?l>z{M9x+xPK|p-*EkdlX>5?hD@DBx^C3D%%Yh&C4jt4 zZqJq)!FYMLitkoa5YLLR1{M1&UnT~{sg}*r&94));N5qoZZk}Zb;#`ps9NW;|5L&E z*ZB|sI=Z^3jmmYz+(gC+o$?k!3%fgQhle>jh`ABwkvAZQ0ElJg4QVcH1Ig0(IjcHG zv9m1B4BhynC&Gl3A@OiLcFMMq18>kaENf=F95qViZ5fXRvN*P|$pvFwDzhe3o_TRj z=K-y^ko4NLjL&B=0>ux~Mj?zdzvg zNvC^Xq(|xxFSXsZkAVNzuHw_{tVE^Yp(-XYAZZ-PB5-{l;BZn&1k|Qs7%fH^cEH{5 zFyKKPhNym6xD@y{_FKpXE2EQ*>CARx+Wv$b-_VAy_1m1|y|ZZzPp(e2C^us#C4tV~ z8jbAjS{b`ipu<57@k)#U&f`s|gFZ?2kN zqve3%cuV(RvQW0!kcth84uuCu>tLDCQ%FzshEkqzLF%jisNj zA)Ur%Urk?Hi;0PCy9svhw@2p=kGIxU;yi{{=iKRz3!_ z4Jvy8K_E&JWLotM3SAa66H5H*Z|eQPjmgPQ>8?S!0K`8+gcX>7 zOmx>GzBD))Z5{&j8^i$t&dw<_KyOFS%{LIDS~ClL=q7wpkk;cjDSAJ&=@jLZY}|& z|H>P;iGWJ+jYFA}?s{$J;nzg^uIjJPm+@2bPN>Q-6`oePjRgT6il&HYoZ&v;uhaGT z(nXcj4#)=G%s=xWeh#28%B@LPeV7^_k5-HG?hA=`q#7@{xVf{o;FBauZaAA6m(2Z355F)Tx zxWx7C><#;mOz@vX-l=&)o?=oI6Ih-Lsi^&vJi ziRxh$0=a16y3k5Y?qQQ^g!TopEGA%`ScgoX42W8-8LHAyz@g8tp5UxL_O!N^W zI(xypWG4u)3;^zO5dgiMK~J~a6AyCeUoj!+g!coo@d+EuU_I&{70*S}d$Rk5gr||f ztLxyzM;t-bOww}lM}5b4-1gPIf3RWgZ>x09-~Lmr+}%zgSg7UH!j{dMR#3J>6@(Ep zMpR>2s)D7+DK&R`b1{;J_pg0>>*glJomdBhy3nbX)Lh7H`L{%w8;%sDC2iY`+5&Q! zf#ez>1T`HPSR3ZO+A`CS=7V+_1B9iO4X5Xv{`?-IuYV0p7ok=Dy*OvTwkeVDA{!p3 zcN28Nx~gVCR%%Si>>UZf`H`qEYh*G58?s&ccJXs`o2!XZW1=E57<{K9% zN)2j6a(`~749(>t)zRy+jPYaV760dx6EU~A^-B#A$}~aWS9#Vaik6XU;PVmC$~U10 z=&&>ntmVs20Paj|pT684)&Rkshx5;KMDXlV>VS`L^>_30!fk-IdnFMrPlg}yxw(oU z(B5U+f7^dteUP`OkiMrDo*olQGz2R3DWNlmZt-%LpX*yr6iI zOwP6r2oA|SSPR0;iYpK~_PJyy`hb_5Kl-1~X&3KoV7!G&CKwZBM`@VekJa0oF34Mu zP!#;mTs{a54i%d4dEUtK_W1lg3Ox$+eJ)K}s6?M%p9t+4O}PW#9tuC}MFK3D->?WK zfLT}%Yf7J^pJpBaW*D}hxH(Vqn~gW){_BujA{cbfu7|-urr=y6z|PFiTMsD~cpT4{ zV}=bJsFcqj{NA7ajKQMnaY=&idEkw%VGFCqynTR!!Hvo4T#$=hI4?5cb&1DQ0QT)# zpS!yVkxLx55ER0_rpO{$RBCXJG^+AP?|l6_Be14kj}KJa}h+ zItqaN^}NjfxEy=+Q=L!9Sk@_||A*3t2!6vZhhr4F1c3LQ(@U*C_l@SkQo;$Xh}RiW zEj(he@vp9VJ%97d7NrOIS(-k_aG2H%*M<-!v0l-AWSd@eiPa)0)y8d(Wd=P=azyF#vi{K zl0ZU>Lj@`ogax9rDqwoY590D2ytfI-xU72&we^$99tMvu+^1eX4p8WT$invYoAT?G zg$E?3;lewGbv)9(WTLP4lOyJ&zwh5M-SphhK8z4<;GoSA0B|_4B&yf=5~Ns z4%)U8Y=|jN7j#<;*^WNWxOWs4-vQp#2yh(!4o9T&HA%vsKD7m zOUaeZA|UBI24Y=nwj(HN(%*$DWtyV&2-#e@=uBX;GDtOu)r&H4w5l?}9FyT$y1`Xr z_*Pu;-(?HpOxr7Wb%dxRJXrhRC{#;gJCG;MaPI<(c)8QY-{su-!V0`{?thFO23tQD z?TZ(q$-Es5O&R29<0K^fysToB;8#1n# zBISl!BXlakNMNhJMg2EET!Ddz6`GT_u8Ih<>-%pTbQz&>g0yc^v9&WgROIYRymB|j z{Zk7fv<FFe6D~Z1(g*$ay9#fpSO{+Ie$i zfGM4usD7-m6G-AmmY-j}?O*z2)$69E+HYb9 z_>GWA`duZVI+&kZnaXU5Wen+Px?Z14_`udbVR7t6_a~b=v{gwQsidmsm|tCT*V3&x10n=ifw~P9-;n^TBKb@J#}`Wi+!?^}r!*;7jj)WQoh9 z?9zf?XMVjCTq0yxpnX1%uQo@Qgr>=uq3H=*R-YHH^08lBj`AfnoT*l` z%D5u#p@uxTyUC1st868dN8pN7HvgD~m-%wLiEB(_ZQ=34#^EzB= z3DW%IMdF2K3<%Q&=fTQS;tDFkLyh^G3cV6jWD2ybHs zJ1?2FAvn3+7vRQ>n<~d|8DS4Ky5gqVF zly{!irYjq@Fyu3DnEU-&g-K;jSt5ETa1~mHmpBRQAdL2N!`okfDJS^jsiM8Ut2?G} zX3$)4aZlZWvD!|;cFSchdE$ny+(`7uXV{v9u$@iEelcirk5LUw<9W=Db7z&WF&gwq zghlD%Z`(s5j>9yER%Ip2(-f@85XRrD?Mj9sqlHyTQ58v+%^}A72UECHu(^HLfsx z@?7(1za|aOp;&}&*tBF9i@qVe>8*|TuFGPrq8rv2a%B%c+qBSqH)k48Ru>;6M&e3q z*mVwdH$%g7V{F>O%1{~LWGg4fm~BAeht!_Qfkz)JU=eol3|H?Ls?i<-VBFQM!cxf_ z74l1#BMs=qbd(N{fWrwCBA$Y?#P<)X9?}z(X4B0z#q`#Tu+G5W&tr@-Qe#7<2$ce= zYWZfPMGRUdQioB?2_5PA?Nu8SHCGqwmRKgL|GMzGN6YFfAE46c{*fme?o%&qswP!X zgFA0&Je$#g!?)c3c(QP{YsiJ;DSXk*n>~R0C(1pt$)CJG5L8F8la9;4MlDlVRK`#mN|;S8{qc5r=)9sk zgg&{#rA_O8uX0<6N9ZZy6XS)#)?_G&FLj=t5d!pi2BcS{heFwKD<=h^GRN=(Cv?39 zss7@M$B4JGDZcYcyhO-2w5bp-Cxr>zr6Z!Tsxn|^-i@$KN|a-7{vM!75jUTK#2$xS zQx8JsD6kvt#ipS#`;D;Yh+@Scvhf5XbqEdH*Rx2^EWvfnau5B4n=wHIL4$Vi6Kk=8 zk58v=tJh@ra-TryyRMHBn)5g*^cwQ?qs>c?9!sL*->7sL!W22_svY-oa-=QMtAWV0 z#K?h$hD7D5g>tejK2FNw$5$NB^Nk7FMh?MmBMRZUc;^YBb)X1|G3Om`8rp7s%C2>y-_Zu=Bx;6~u zuaFbgh7woqp_Ov8mpA1Z0%!{P|=j8cvd4U`9cH^m7>A zkyIt!r%*1`$SGZFumKq+&YLw6BSYJjCh|6xRL=N1p{WuT5I39PuYFle2m`-zHZfNc z|8xtS(Md=vq!3mKZ>G{jZX^6U46DT-4rX0VH~uSPt|ZRLn2JIXr~~<6R)XSL$;Nkg zVbR9R+<8P54wO9H(ZHj70|NH$JOy0<2L+SBrrZ;pG4niL-kX%dvNW5lL5N}F2V|4O zTp_9D?XBdE<2=juizS3BG)lfa(vda7*Ah4U{(=WRwV-UgU3C5lu< zp%B=ceSWgQy?)o^h-)+Hx;eT=cvNSTt(UmK(NMHnUU7~`S4eIy9RvCz#+>JMt7~f0 zUvYescyKNfk~Z>H0}C5<*D)i@lXu9yQ?_-x0{l(UGjl`YbB59n1|W8fyU*3QpInrh z@Y#CVgb!(zD%+FUud=wv(Pz?jX*Y3u(@7<=4&3LdnL^h72MA3TRYIcu;`X)>+e#aK zC33rOVI4}n?;L(Hum^pg^|`&QN+^JIdf?Cf^B40Hw;&Hd%H`$e<|fyW<&Y?^N)y7e z7%t|&3NEuoIFL&#v8=}3Xi%Q6+~HeQufQs{sQLg`(Qt0AtuSrAeNj9oOJsxxB!}jO zLf#S@umiI+tV_n0I65?juo)|r5NA44&0#imJM+5O3CF+F_hWLSxw>tIXlA?bi@$Bu zI%?_L?73(#$|vAnd;f(ogE)Q@aZ}B@>uZ7W!uf~y*9g8GI>OOReA*5J31THKQ#xPn8F#59;=*Gw@rZ_h=~mblpH>~BBgNMVq-&C)4#Zr zZ5C3r*P<9(x|$ynu^p^^|Dck==(+KX2z)D|k5i1EJK(xakk+2@4|tpEzR30nyF^pN zA~K+-=x(=yUXS)2pj**9oRY8QX-yHJjdm2iMuj~7Rlx9I;sebpflt51J1-DH>i9$H zd>nyRN3YaLF-GLK)WIA9;Aqx;NOSZ-IRp9`lHNqXYH^|RIp`}J5&XeiE zjNGf-R066&igI3m1jk`^$X#tn_2Fuav}N(@s3Ptz0!6}2VH*p10{!fYD(m&xhI=t$ ze{l}8FBzpid{eK>v0XyzU7>q4BD85uTcj2-pP|0dmdp+J#|%D0gKOM$`0 zqy7viG6Rp344H*kIk?+xKHi6+;>Va;u=_}~pM-D6LsE!?DbCHEoLg~v^X^`W=d6N z3ltV=$_%yQRt|s88@6N+{fK@WT0=o+ba}BMW`pwc77AZ0=29`{`!@iMqYj&3{Z0+9 z%F;~35DJdP622eFGkpbGU!f3FlVi+>feYz7n`Ze#k zq7fNqP}zuP`cH_0$M>9eeh*zUa(w`FiGT*$d0bDy6qy#x36xs2)}YU1f~Rnm$gBgv z9Oy`fV7tr`{)aCEzism;mMr}%+0A7XH-P4YeggQ>{=#8Z>zPjb8a zndEw1>OibbUBrtH`(6#vi(qv-DV#)N9ekpJ3>Qeg%}Jm-~S-=n2lc|H85?!37(D zCk^|~wj1c<#NJ2v?h$=IUG?_kbUP)>F!E5o`ppfsuUT≷u5xvLDnt?f-?DHoeu$ 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%0DB( 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

v!d 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